-
Notifications
You must be signed in to change notification settings - Fork 7
Create OBI-compatible icache wrapper #5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
micprog
wants to merge
7
commits into
main
Choose a base branch
from
michaero/pulp_wrapper
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+588
−298
Open
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
133f28c
Create wrapper for PULP cluster
micprog 016ed7b
Extract l0_to_bypass module to independent file
micprog c8cde36
Extract axi_burst_splitter_table module to independent file
micprog e85090a
Rename pulp_icache_wrap to obi_icache_wrap
micprog 4362489
update changelog
micprog e7e9de3
obi_icache_wrap: Propagate parameters from icache
micprog 0860887
obi_icache_wrap: fix performance events
micprog File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,161 @@ | ||
| // Copyright 2021 ETH Zurich and University of Bologna. | ||
| // Solderpad Hardware License, Version 0.51, see LICENSE for details. | ||
| // SPDX-License-Identifier: SHL-0.51 | ||
|
|
||
| // Author: Samuel Riedel <sriedel@iis.ee.ethz.ch> | ||
| // | ||
| // Adapted from the axi_burst_splitter authored by: | ||
| // Andreas Kurth <akurth@iis.ee.ethz.ch> | ||
| // Florian Zaruba <zarubaf@iis.ee.ethz.ch> | ||
| // Wolfgang Roenninger <wroennin@iis.ee.ethz.ch> | ||
|
|
||
| `include "common_cells/registers.svh" | ||
| /// Stores the burst length and the corresponding address offset for the axi_to_cache module. | ||
| /// Adapted from axi_burst_splitter_counters | ||
| module axi_burst_splitter_table #( | ||
| parameter int unsigned MaxTrans = 0, | ||
| parameter int unsigned IdWidth = 0, | ||
| parameter type offset_t = logic, | ||
| parameter type id_t = logic [IdWidth-1:0] | ||
| ) ( | ||
| input logic clk_i, | ||
| input logic rst_ni, | ||
|
|
||
| input id_t alloc_id_i, | ||
| input axi_pkg::len_t alloc_len_i, | ||
| input offset_t alloc_offset_i, | ||
| input logic alloc_req_i, | ||
| output logic alloc_gnt_o, | ||
|
|
||
| input id_t cnt_id_i, | ||
| output axi_pkg::len_t cnt_len_o, | ||
| output offset_t cnt_offset_o, | ||
| input logic cnt_set_err_i, | ||
| output logic cnt_err_o, | ||
| input logic cnt_len_dec_i, | ||
| input logic cnt_offset_inc_i, | ||
| input logic cnt_req_i, | ||
| output logic cnt_gnt_o | ||
| ); | ||
| localparam int unsigned CntIdxWidth = (MaxTrans > 1) ? $clog2(MaxTrans) : 32'd1; | ||
|
|
||
| typedef logic [CntIdxWidth-1:0] cnt_idx_t; | ||
| typedef logic [$bits(axi_pkg::len_t):0] cnt_t; | ||
|
|
||
| cnt_idx_t cnt_free_idx, cnt_r_idx; | ||
| logic [MaxTrans-1:0] cnt_len_dec, cnt_offset_inc, cnt_free, cnt_set, err_d, err_q; | ||
| cnt_t cnt_len_inp; | ||
| cnt_t [MaxTrans-1:0] cnt_len_oup; | ||
| offset_t cnt_offset_inp; | ||
| offset_t [MaxTrans-1:0] cnt_offset_oup; | ||
| for (genvar i = 0; i < MaxTrans; i++) begin : gen_cnt | ||
| counter #( | ||
| .WIDTH ( $bits(cnt_t) ) | ||
| ) i_cnt_len ( | ||
| .clk_i, | ||
| .rst_ni, | ||
| .clear_i ( 1'b0 ), | ||
| .en_i ( cnt_len_dec[i] ), | ||
| .load_i ( cnt_set[i] ), | ||
| .down_i ( 1'b1 ), | ||
| .d_i ( cnt_len_inp ), | ||
| .q_o ( cnt_len_oup[i] ), | ||
| .overflow_o ( ) // not used | ||
| ); | ||
| counter #( | ||
| .WIDTH ( $bits(offset_t) ) | ||
| ) i_cnt_offset ( | ||
| .clk_i, | ||
| .rst_ni, | ||
| .clear_i ( 1'b0 ), | ||
| .en_i ( cnt_offset_inc[i] ), | ||
| .load_i ( cnt_set[i] ), | ||
| .down_i ( 1'b0 ), | ||
| .d_i ( cnt_offset_inp ), | ||
| .q_o ( cnt_offset_oup[i] ), | ||
| .overflow_o ( ) // not used | ||
| ); | ||
| assign cnt_free[i] = (cnt_len_oup[i] == '0); | ||
| end | ||
| assign cnt_len_inp = {1'b0, alloc_len_i} + 1; | ||
| assign cnt_offset_inp = alloc_offset_i; | ||
|
|
||
| lzc #( | ||
| .WIDTH ( MaxTrans ), | ||
| .MODE ( 1'b0 ) | ||
| ) i_lzc ( | ||
| .in_i ( cnt_free ), | ||
| .cnt_o ( cnt_free_idx ), | ||
| .empty_o ( ) | ||
| ); | ||
|
|
||
| logic idq_inp_req, idq_inp_gnt; | ||
| logic idq_oup_gnt, idq_oup_valid, idq_oup_pop; | ||
| id_queue #( | ||
| .ID_WIDTH ( $bits(id_t) ), | ||
| .CAPACITY ( MaxTrans ), | ||
| .FULL_BW ( 1'b1 ), | ||
| .data_t ( cnt_idx_t ) | ||
| ) i_idq ( | ||
| .clk_i, | ||
| .rst_ni, | ||
| .inp_id_i ( alloc_id_i ), | ||
| .inp_data_i ( cnt_free_idx ), | ||
| .inp_req_i ( idq_inp_req ), | ||
| .inp_gnt_o ( idq_inp_gnt ), | ||
| .exists_data_i ( '0 ), | ||
| .exists_mask_i ( '0 ), | ||
| .exists_req_i ( 1'b0 ), | ||
| .exists_o ( /* unused */ ), | ||
| .exists_gnt_o ( /* unused */ ), | ||
| .oup_id_i ( cnt_id_i ), | ||
| .oup_pop_i ( idq_oup_pop ), | ||
| .oup_req_i ( cnt_req_i ), | ||
| .oup_data_o ( cnt_r_idx ), | ||
| .oup_data_valid_o ( idq_oup_valid ), | ||
| .oup_gnt_o ( idq_oup_gnt ) | ||
| ); | ||
| logic [8:0] read_len; | ||
| assign idq_inp_req = alloc_req_i & alloc_gnt_o; | ||
| assign alloc_gnt_o = idq_inp_gnt & |(cnt_free); | ||
| assign cnt_gnt_o = idq_oup_gnt & idq_oup_valid; | ||
| assign read_len = cnt_len_oup[cnt_r_idx] - 1; | ||
| assign cnt_len_o = read_len[7:0]; | ||
| assign cnt_offset_o = cnt_offset_oup[cnt_r_idx]; | ||
| assign idq_oup_pop = cnt_req_i & cnt_gnt_o & cnt_len_dec_i & (cnt_len_o == 8'd0); | ||
|
|
||
| always_comb begin | ||
| cnt_len_dec = '0; | ||
| cnt_len_dec[cnt_r_idx] = cnt_req_i & cnt_gnt_o & cnt_len_dec_i; | ||
| end | ||
| always_comb begin | ||
| cnt_offset_inc = '0; | ||
| cnt_offset_inc[cnt_r_idx] = cnt_req_i & cnt_gnt_o & cnt_offset_inc_i; | ||
| end | ||
| always_comb begin | ||
| cnt_set = '0; | ||
| cnt_set[cnt_free_idx] = alloc_req_i & alloc_gnt_o; | ||
| end | ||
| always_comb begin | ||
| err_d = err_q; | ||
| cnt_err_o = err_q[cnt_r_idx]; | ||
| if (cnt_req_i && cnt_gnt_o && cnt_set_err_i) begin | ||
| err_d[cnt_r_idx] = 1'b1; | ||
| cnt_err_o = 1'b1; | ||
| end | ||
| if (alloc_req_i && alloc_gnt_o) begin | ||
| err_d[cnt_free_idx] = 1'b0; | ||
| end | ||
| end | ||
|
|
||
| // registers | ||
| `FF(err_q, err_d, '0, clk_i, rst_ni) | ||
|
|
||
| `ifndef VERILATOR | ||
| // pragma translate_off | ||
| assume property (@(posedge clk_i) idq_oup_gnt |-> idq_oup_valid) | ||
| else begin $warning("Invalid output at ID queue, read not granted!"); $finish(); end | ||
| // pragma translate_on | ||
| `endif | ||
|
|
||
| endmodule |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,152 @@ | ||
| // Copyright 2020 ETH Zurich and University of Bologna. | ||
| // Solderpad Hardware License, Version 0.51, see LICENSE for details. | ||
| // SPDX-License-Identifier: SHL-0.51 | ||
|
|
||
| // Fabian Schuiki <fschuiki@iis.ee.ethz.ch> | ||
| // Florian Zaruba <zarubaf@iis.ee.ethz.ch> | ||
|
|
||
| `include "common_cells/registers.svh" | ||
|
|
||
| // Translate register interface to refill requests. | ||
| // Used for bypassable accesses. | ||
| module l0_to_bypass #( | ||
| parameter snitch_icache_pkg::config_t CFG = '0 | ||
| ) ( | ||
| input logic clk_i, | ||
| input logic rst_ni, | ||
|
|
||
| input logic [CFG.NR_FETCH_PORTS-1:0] in_valid_i, | ||
| output logic [CFG.NR_FETCH_PORTS-1:0] in_ready_o, | ||
| input logic [CFG.NR_FETCH_PORTS-1:0][CFG.FETCH_AW-1:0] in_addr_i, | ||
| output logic [CFG.NR_FETCH_PORTS-1:0][CFG.FETCH_DW-1:0] in_data_o, | ||
| output logic [CFG.NR_FETCH_PORTS-1:0] in_error_o, | ||
|
|
||
| output logic [CFG.FETCH_AW-1:0] refill_req_addr_o, | ||
| output logic refill_req_bypass_o, | ||
| output logic refill_req_valid_o, | ||
| input logic refill_req_ready_i, | ||
|
|
||
| input logic [CFG.LINE_WIDTH-1:0] refill_rsp_data_i, | ||
| input logic refill_rsp_error_i, | ||
| input logic refill_rsp_valid_i, | ||
| output logic refill_rsp_ready_o | ||
| ); | ||
|
|
||
| assign refill_req_bypass_o = 1'b1; | ||
|
|
||
| logic [CFG.NR_FETCH_PORTS-1:0] in_valid; | ||
| logic [CFG.NR_FETCH_PORTS-1:0] in_ready; | ||
|
|
||
| typedef enum logic [1:0] { | ||
| Idle, RequestData, WaitResponse, PresentResponse | ||
| } state_e; | ||
| state_e [CFG.NR_FETCH_PORTS-1:0] state_d , state_q; | ||
|
|
||
| // Mask address so that it is aligned to the cache-line width. | ||
| logic [CFG.NR_FETCH_PORTS-1:0][CFG.FETCH_AW-1:0] in_addr_masked; | ||
| for (genvar i = 0; i < CFG.NR_FETCH_PORTS; i++) begin : gen_masked_addr | ||
| assign in_addr_masked[i] = {in_addr_i[i][CFG.FETCH_AW-1:CFG.LINE_ALIGN], | ||
| {CFG.LINE_ALIGN{1'b0}}}; | ||
| end | ||
| stream_arbiter #( | ||
| .DATA_T ( logic [CFG.FETCH_AW-1:0] ), | ||
| .N_INP ( CFG.NR_FETCH_PORTS ) | ||
| ) i_stream_arbiter ( | ||
| .clk_i, | ||
| .rst_ni, | ||
| .inp_data_i ( in_addr_masked ), | ||
| .inp_valid_i ( in_valid ), | ||
| .inp_ready_o ( in_ready ), | ||
| .oup_data_o ( refill_req_addr_o ), | ||
| .oup_valid_o ( refill_req_valid_o ), | ||
| .oup_ready_i ( refill_req_ready_i ) | ||
| ); | ||
|
|
||
| localparam int unsigned NrFetchPortsBin = | ||
| CFG.NR_FETCH_PORTS == 1 ? 1 : $clog2(CFG.NR_FETCH_PORTS); | ||
|
|
||
| logic [CFG.NR_FETCH_PORTS-1:0] rsp_fifo_mux; | ||
| logic [NrFetchPortsBin-1:0] onehot_mux; | ||
| logic [CFG.NR_FETCH_PORTS-1:0] rsp_fifo_pop; | ||
| logic rsp_fifo_full; | ||
|
|
||
| logic [CFG.NR_FETCH_PORTS-1:0] rsp_valid; | ||
| logic [CFG.NR_FETCH_PORTS-1:0] rsp_ready; | ||
|
|
||
| fifo_v3 #( | ||
| .DATA_WIDTH ( CFG.NR_FETCH_PORTS ), | ||
| .DEPTH ( 4 ) | ||
| ) rsp_fifo ( | ||
| .clk_i, | ||
| .rst_ni, | ||
| .flush_i ( 1'b0 ), | ||
| .testmode_i ( 1'b0 ), | ||
| .full_o ( rsp_fifo_full ), | ||
| .empty_o ( ), | ||
| .usage_o ( ), | ||
| .data_i ( {in_valid & in_ready} ), | ||
| .push_i ( |{in_valid & in_ready}), | ||
| .data_o ( rsp_fifo_mux ), | ||
| .pop_i ( |rsp_fifo_pop ) | ||
| ); | ||
|
|
||
|
|
||
| onehot_to_bin #( | ||
| .ONEHOT_WIDTH (CFG.NR_FETCH_PORTS) | ||
| ) i_onehot_to_bin ( | ||
| .onehot (rsp_fifo_mux), | ||
| .bin (onehot_mux) | ||
| ); | ||
|
|
||
| assign rsp_ready = '1; | ||
|
|
||
| stream_demux #( | ||
| .N_OUP ( CFG.NR_FETCH_PORTS ) | ||
| ) i_stream_mux_miss_refill ( | ||
| .inp_valid_i ( refill_rsp_valid_i ), | ||
| .inp_ready_o ( refill_rsp_ready_o ), | ||
| .oup_sel_i ( onehot_mux ), | ||
| .oup_valid_o ( rsp_valid ), | ||
| .oup_ready_i ( rsp_ready ) | ||
| ); | ||
|
|
||
| for (genvar i = 0; i < CFG.NR_FETCH_PORTS; i++) begin : gen_bypass_request | ||
| always_comb begin | ||
| state_d[i] = state_q[i]; | ||
| in_ready_o[i] = 1'b0; | ||
| rsp_fifo_pop[i] = 1'b0; | ||
| in_valid[i] = 1'b0; | ||
| unique case (state_q[i]) | ||
| // latch data when idle | ||
| Idle: if (in_valid_i[i]) state_d[i] = RequestData; | ||
| RequestData: begin | ||
| // check that there is still space for the response to be accepted. | ||
| if (!rsp_fifo_full) begin | ||
| in_valid[i] = 1'b1; | ||
| if (in_ready[i]) state_d[i] = WaitResponse; | ||
| end | ||
| end | ||
| WaitResponse: begin | ||
| if (rsp_valid[i]) begin | ||
| rsp_fifo_pop[i] = 1'b1; | ||
| state_d[i] = PresentResponse; | ||
| end | ||
| end | ||
| // The response will be served from the register and is valid for one cycle. | ||
| PresentResponse: begin | ||
| state_d[i] = Idle; | ||
| in_ready_o[i] = 1'b1; | ||
| end | ||
| default:; | ||
| endcase | ||
| end | ||
| logic [CFG.FILL_DW-1:0] fill_rsp_data; | ||
| assign fill_rsp_data = | ||
| refill_rsp_data_i >> (in_addr_i[i][CFG.LINE_ALIGN-1:CFG.FETCH_ALIGN] * CFG.FETCH_DW); | ||
| `FFLNR({in_data_o[i], in_error_o[i]}, {fill_rsp_data[CFG.FETCH_DW-1:0], refill_rsp_error_i}, | ||
| rsp_valid[i], clk_i) | ||
| end | ||
|
|
||
| `FF(state_q, state_d, '{default: Idle}) | ||
|
|
||
| endmodule |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.