diff --git a/Bender.yml b/Bender.yml index c1546b35..a390de7f 100644 --- a/Bender.yml +++ b/Bender.yml @@ -31,6 +31,7 @@ sources: - src/floo_wormhole_arbiter.sv - src/floo_simple_rob.sv - src/floo_rob.sv + - src/floo_rob_wrapper.sv - src/floo_meta_buffer.sv # Level 2 - src/floo_axi_chimney.sv diff --git a/CHANGELOG.md b/CHANGELOG.md index 29c9e03c..65d73afa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) - Table based routing support in `narrow_wide_chimney` - Support for different number of inputs and outputs in `narrow_wide_router` +- Add wrapper for different types of Reorder Buffers in chimneys +- Support for simple RoB-less chimneys with ID counters ### Fixed diff --git a/src/floo_axi_chimney.sv b/src/floo_axi_chimney.sv index a694ad8a..8f2cb71b 100644 --- a/src/floo_axi_chimney.sv +++ b/src/floo_axi_chimney.sv @@ -34,9 +34,6 @@ module floo_axi_chimney parameter int unsigned MaxTxnsPerId = MaxTxns, /// Capacity of the reorder buffer parameter int unsigned ReorderBufferSize = 32, - /// Choice between simple or advanced reorder buffer, - /// trade-off between area and performance - parameter bit RoBSimple = 1'b0, /// Only used for XYRouting parameter type xy_id_t = logic, /// Cut timing paths of outgoing requests @@ -74,11 +71,6 @@ module floo_axi_chimney logic axi_aw_queue_valid_out, axi_aw_queue_ready_in; logic axi_ar_queue_valid_out, axi_ar_queue_ready_in; - axi_in_req_t axi_out_req_id_mapped; - axi_in_rsp_t axi_out_rsp_id_mapped; - `AXI_ASSIGN_REQ_STRUCT(axi_out_req_o, axi_out_req_id_mapped) - `AXI_ASSIGN_RESP_STRUCT(axi_out_rsp_id_mapped, axi_out_rsp_i) - floo_req_chan_t [AxiAw:AxiAr] floo_req_arb_in; floo_rsp_chan_t [AxiB:AxiR] floo_rsp_arb_in; logic [AxiAw:AxiAr] floo_req_arb_req_in, floo_req_arb_gnt_out; @@ -92,13 +84,11 @@ module floo_axi_chimney logic [NumAxiChannels-1:0] axi_valid_in, axi_ready_out; // Flit packing - floo_axi_aw_flit_t floo_axi_aw; - floo_axi_w_flit_t floo_axi_w; + floo_axi_aw_flit_t floo_axi_aw; + floo_axi_w_flit_t floo_axi_w; floo_axi_ar_flit_t floo_axi_ar; - floo_axi_b_flit_t floo_axi_b; - floo_axi_r_flit_t floo_axi_r; - axi_in_aw_chan_t axi_aw_id_mod; - axi_in_ar_chan_t axi_ar_id_mod; + floo_axi_b_flit_t floo_axi_b; + floo_axi_r_flit_t floo_axi_r; // Flit unpacking axi_in_aw_chan_t axi_unpack_aw; @@ -109,6 +99,12 @@ module floo_axi_chimney floo_req_generic_flit_t unpack_req_generic; floo_rsp_generic_flit_t unpack_rsp_generic; + // Meta Buffer + axi_in_req_t axi_meta_buf_req_in, axi_meta_buf_req_out; + axi_in_rsp_t axi_meta_buf_rsp_in, axi_meta_buf_rsp_out; + `AXI_ASSIGN_REQ_STRUCT(axi_out_req_o, axi_meta_buf_req_out) + `AXI_ASSIGN_RESP_STRUCT(axi_meta_buf_rsp_in, axi_out_rsp_i) + // Flit arbitration typedef enum logic {SelAw, SelW} aw_w_sel_e; aw_w_sel_e aw_w_sel_q, aw_w_sel_d; @@ -128,12 +124,6 @@ module floo_axi_chimney id_t [NumAxiChannels-1:0] dst_id; id_t src_id; - logic aw_out_push, aw_out_pop; - logic ar_out_push, ar_out_pop; - logic aw_out_full; - logic ar_out_full; - axi_out_id_t aw_out_id; - axi_out_id_t ar_out_id; id_out_buf_t aw_out_data_in, aw_out_data_out; id_out_buf_t ar_out_data_in, ar_out_data_out; @@ -244,11 +234,13 @@ module floo_axi_chimney `ASSERT(NoAtopSupport, !(axi_aw_queue_valid_out && (axi_aw_queue.atop != axi_pkg::ATOP_NONE))) end - floo_simple_rob #( + floo_rob_wrapper #( + .RoBType ( NoRoB ), .ReorderBufferSize ( ReorderBufferSize ), .MaxRoTxnsPerId ( MaxTxnsPerId ), .OnlyMetaData ( 1'b1 ), .ax_len_t ( axi_pkg::len_t ), + .ax_id_t ( axi_in_id_t ), .rsp_chan_t ( axi_in_b_chan_t ), .rsp_meta_t ( axi_in_b_chan_t ), .rob_idx_t ( rob_idx_t ), @@ -261,6 +253,7 @@ module floo_axi_chimney .ax_valid_i ( aw_rob_valid_in ), .ax_ready_o ( aw_rob_ready_out ), .ax_len_i ( axi_aw_queue.len ), + .ax_id_i ( axi_aw_queue.id ), .ax_dest_i ( dst_id[AxiAw] ), .ax_valid_o ( aw_rob_valid_out ), .ax_ready_i ( aw_rob_ready_in ), @@ -285,76 +278,43 @@ module floo_axi_chimney logic last; } r_rob_meta_t; - if (RoBSimple) begin : gen_simple_rob - floo_simple_rob #( - .ReorderBufferSize ( ReorderBufferSize ), - .MaxRoTxnsPerId ( MaxTxnsPerId ), - .OnlyMetaData ( 1'b0 ), - .ax_len_t ( axi_pkg::len_t ), - .rsp_chan_t ( axi_in_r_chan_t ), - .rsp_data_t ( r_rob_data_t ), - .rsp_meta_t ( r_rob_meta_t ), - .rob_idx_t ( rob_idx_t ), - .dest_t ( id_t ), - .sram_cfg_t ( sram_cfg_t ) - ) i_r_rob ( - .clk_i, - .rst_ni, - .sram_cfg_i, - .ax_valid_i ( axi_ar_queue_valid_out ), - .ax_ready_o ( axi_ar_queue_ready_in ), - .ax_len_i ( axi_ar_queue.len ), - .ax_dest_i ( dst_id[AxiAr] ), - .ax_valid_o ( ar_rob_valid_out ), - .ax_ready_i ( ar_rob_ready_in ), - .ax_rob_req_o ( ar_rob_req_out ), - .ax_rob_idx_o ( ar_rob_idx_out ), - .rsp_valid_i ( r_rob_valid_in ), - .rsp_ready_o ( r_rob_ready_out ), - .rsp_i ( axi_r_rob_in ), - .rsp_rob_req_i ( floo_rsp_in.axi_r.hdr.rob_req ), - .rsp_rob_idx_i ( floo_rsp_in.axi_r.hdr.rob_idx ), - .rsp_last_i ( floo_rsp_in.axi_r.hdr.last ), - .rsp_valid_o ( r_rob_valid_out ), - .rsp_ready_i ( r_rob_ready_in ), - .rsp_o ( axi_r_rob_out ) - ); - end else begin : gen_rob - floo_rob #( - .ReorderBufferSize ( ReorderBufferSize ), - .MaxRoTxnsPerId ( MaxTxnsPerId ), - .OnlyMetaData ( 1'b0 ), - .ax_len_t ( axi_pkg::len_t ), - .ax_id_t ( axi_in_id_t ), - .rsp_chan_t ( axi_in_r_chan_t ), - .rsp_data_t ( r_rob_data_t ), - .rsp_meta_t ( r_rob_meta_t ), - .dest_t ( id_t ), - .sram_cfg_t ( sram_cfg_t ) - ) i_r_rob ( - .clk_i, - .rst_ni, - .sram_cfg_i, - .ax_valid_i ( axi_ar_queue_valid_out ), - .ax_ready_o ( axi_ar_queue_ready_in ), - .ax_len_i ( axi_ar_queue.len ), - .ax_id_i ( axi_ar_queue.id ), - .ax_dest_i ( dst_id[AxiAr] ), - .ax_valid_o ( ar_rob_valid_out ), - .ax_ready_i ( ar_rob_ready_in ), - .ax_rob_req_o ( ar_rob_req_out ), - .ax_rob_idx_o ( ar_rob_idx_out ), - .rsp_valid_i ( r_rob_valid_in ), - .rsp_ready_o ( r_rob_ready_out ), - .rsp_i ( axi_r_rob_in ), - .rsp_rob_req_i ( floo_rsp_in.axi_r.hdr.rob_req ), - .rsp_rob_idx_i ( floo_rsp_in.axi_r.hdr.rob_idx ), - .rsp_last_i ( floo_rsp_in.axi_r.hdr.last ), - .rsp_valid_o ( r_rob_valid_out ), - .rsp_ready_i ( r_rob_ready_in ), - .rsp_o ( axi_r_rob_out ) - ); - end + + floo_rob_wrapper #( + .RoBType ( NoRoB ), + .ReorderBufferSize ( ReorderBufferSize ), + .MaxRoTxnsPerId ( MaxTxnsPerId ), + .OnlyMetaData ( 1'b0 ), + .ax_len_t ( axi_pkg::len_t ), + .ax_id_t ( axi_in_id_t ), + .rsp_chan_t ( axi_in_r_chan_t ), + .rsp_data_t ( r_rob_data_t ), + .rsp_meta_t ( r_rob_meta_t ), + .rob_idx_t ( rob_idx_t ), + .dest_t ( id_t ), + .sram_cfg_t ( sram_cfg_t ) + ) i_r_rob ( + .clk_i, + .rst_ni, + .sram_cfg_i, + .ax_valid_i ( axi_ar_queue_valid_out ), + .ax_ready_o ( axi_ar_queue_ready_in ), + .ax_len_i ( axi_ar_queue.len ), + .ax_id_i ( axi_ar_queue.id ), + .ax_dest_i ( dst_id[AxiAr] ), + .ax_valid_o ( ar_rob_valid_out ), + .ax_ready_i ( ar_rob_ready_in ), + .ax_rob_req_o ( ar_rob_req_out ), + .ax_rob_idx_o ( ar_rob_idx_out ), + .rsp_valid_i ( r_rob_valid_in ), + .rsp_ready_o ( r_rob_ready_out ), + .rsp_i ( axi_r_rob_in ), + .rsp_rob_req_i ( floo_rsp_in.axi_r.hdr.rob_req ), + .rsp_rob_idx_i ( floo_rsp_in.axi_r.hdr.rob_idx ), + .rsp_last_i ( floo_rsp_in.axi_r.hdr.last ), + .rsp_valid_o ( r_rob_valid_out ), + .rsp_ready_i ( r_rob_ready_in ), + .rsp_o ( axi_r_rob_out ) + ); ///////////////// // ROUTING // @@ -437,7 +397,7 @@ module floo_axi_chimney floo_axi_b.hdr.last = 1'b1; floo_axi_b.hdr.axi_ch = AxiB; floo_axi_b.hdr.atop = aw_out_data_out.atop; - floo_axi_b.b = axi_out_rsp_id_mapped.b; + floo_axi_b.b = axi_meta_buf_rsp_out.b; floo_axi_b.b.id = aw_out_data_out.id; end @@ -450,7 +410,7 @@ module floo_axi_chimney floo_axi_r.hdr.last = axi_out_rsp_i.r.last; floo_axi_r.hdr.axi_ch = AxiR; floo_axi_r.hdr.atop = ar_out_data_out.atop; - floo_axi_r.r = axi_out_rsp_id_mapped.r; + floo_axi_r.r = axi_meta_buf_rsp_out.r; floo_axi_r.r.id = ar_out_data_out.id; end @@ -467,14 +427,12 @@ module floo_axi_chimney axi_aw_queue_valid_out)); assign floo_req_arb_req_in[AxiW] = (aw_w_sel_q == SelW) && axi_in_req_i.w_valid; assign floo_req_arb_req_in[AxiAr] = ar_rob_valid_out; - assign floo_rsp_arb_req_in[AxiB] = axi_out_rsp_i.b_valid; - assign floo_rsp_arb_req_in[AxiR] = axi_out_rsp_i.r_valid; + assign floo_rsp_arb_req_in[AxiB] = axi_meta_buf_rsp_out.b_valid; + assign floo_rsp_arb_req_in[AxiR] = axi_meta_buf_rsp_out.r_valid; assign aw_rob_ready_in = floo_req_arb_gnt_out[AxiAw] && (aw_w_sel_q == SelAw); assign axi_in_rsp_o.w_ready = floo_req_arb_gnt_out[AxiW] && (aw_w_sel_q == SelW); assign ar_rob_ready_in = floo_req_arb_gnt_out[AxiAr]; - assign axi_out_req_id_mapped.b_ready = floo_rsp_arb_gnt_out[AxiB]; - assign axi_out_req_id_mapped.r_ready = floo_rsp_arb_gnt_out[AxiR]; assign floo_req_arb_in[AxiAw] = floo_axi_aw; assign floo_req_arb_in[AxiW] = floo_axi_w; @@ -541,9 +499,9 @@ module floo_axi_chimney assign axi_valid_in[AxiB] = floo_rsp_in_valid && (unpack_rsp_generic.hdr.axi_ch == AxiB); assign axi_valid_in[AxiR] = floo_rsp_in_valid && (unpack_rsp_generic.hdr.axi_ch == AxiR); - assign axi_ready_out[AxiAw] = axi_out_rsp_i.aw_ready && !aw_out_full; - assign axi_ready_out[AxiW] = axi_out_rsp_i.w_ready; - assign axi_ready_out[AxiAr] = axi_out_rsp_i.ar_ready && !ar_out_full; + assign axi_ready_out[AxiAw] = axi_meta_buf_rsp_out.aw_ready; + assign axi_ready_out[AxiW] = axi_meta_buf_rsp_out.w_ready; + assign axi_ready_out[AxiAr] = axi_meta_buf_rsp_out.ar_ready; assign axi_ready_out[AxiB] = b_rob_ready_out || b_sel_atop && axi_in_req_i.b_ready; assign axi_ready_out[AxiR] = r_rob_ready_out || r_sel_atop && axi_in_req_i.r_ready; @@ -554,9 +512,17 @@ module floo_axi_chimney // AXI req/rsp generation // //////////////////////////// - assign axi_out_req_id_mapped.aw_valid = axi_valid_in[AxiAw] && !aw_out_full; - assign axi_out_req_id_mapped.w_valid = axi_valid_in[AxiW]; - assign axi_out_req_id_mapped.ar_valid = axi_valid_in[AxiAr] && !ar_out_full; + assign axi_meta_buf_req_in ='{ + aw : axi_unpack_aw, + aw_valid : axi_valid_in[AxiAw], + w : axi_unpack_w, + w_valid : axi_valid_in[AxiW], + b_ready : floo_rsp_arb_gnt_out[AxiB], + ar : axi_unpack_ar, + ar_valid : axi_valid_in[AxiAr], + r_ready : floo_rsp_arb_gnt_out[AxiR] + }; + assign b_rob_valid_in = axi_valid_in[AxiB] && !is_atop_b_rsp; assign r_rob_valid_in = axi_valid_in[AxiR] && !is_atop_r_rsp; assign axi_in_rsp_o.b_valid = b_rob_valid_out || is_atop_b_rsp; @@ -564,9 +530,6 @@ module floo_axi_chimney assign b_rob_ready_in = axi_in_req_i.b_ready && !b_sel_atop; assign r_rob_ready_in = axi_in_req_i.r_ready && !r_sel_atop; - assign axi_out_req_id_mapped.aw = axi_aw_id_mod; - assign axi_out_req_id_mapped.w = axi_unpack_w; - assign axi_out_req_id_mapped.ar = axi_ar_id_mod; assign axi_b_rob_in = axi_unpack_b; assign axi_r_rob_in = axi_unpack_r; assign axi_in_rsp_o.b = (b_sel_atop)? axi_unpack_b : axi_b_rob_out; @@ -578,13 +541,6 @@ module floo_axi_chimney assign atop_has_r_rsp = AtopSupport && axi_valid_in[AxiAw] && axi_unpack_aw.atop[axi_pkg::ATOP_R_RESP]; - assign aw_out_push = axi_out_req_o.aw_valid && axi_out_rsp_i.aw_ready; - assign ar_out_push = axi_out_req_o.ar_valid && axi_out_rsp_i.ar_ready || - axi_out_req_o.aw_valid && axi_out_rsp_i.aw_ready && - is_atop && atop_has_r_rsp; - assign aw_out_pop = axi_out_rsp_i.b_valid && axi_out_req_o.b_ready; - assign ar_out_pop = axi_out_rsp_i.r_valid && axi_out_req_o.r_ready && axi_out_rsp_i.r.last; - assign aw_out_data_in = '{ id: axi_unpack_aw.id, rob_req: unpack_req_generic.hdr.rob_req, @@ -605,54 +561,24 @@ module floo_axi_chimney .AtopSupport ( AtopSupport ), .MaxAtomicTxns ( MaxAtomicTxns ), .buf_t ( id_out_buf_t ), - .id_t ( axi_out_id_t ) - ) i_aw_meta_buffer ( - .clk_i ( clk_i ), - .rst_ni ( rst_ni ), - .test_enable_i ( test_enable_i ), - .req_push_i ( aw_out_push ), - .req_valid_i ( axi_out_req_o.aw_valid ), - .req_buf_i ( aw_out_data_in ), - .req_is_atop_i ( is_atop ), - .req_atop_id_i ( '0 ), - .req_full_o ( aw_out_full ), - .req_id_o ( aw_out_id ), - .rsp_pop_i ( aw_out_pop ), - .rsp_id_i ( axi_out_rsp_i.b.id ), - .rsp_buf_o ( aw_out_data_out ) - ); - - floo_meta_buffer #( - .MaxTxns ( MaxTxns ), - .AtopSupport ( AtopSupport ), - .MaxAtomicTxns ( MaxAtomicTxns ), - .ExtAtomicId ( 1'b1 ), // Use ID from AW channel - .buf_t ( id_out_buf_t ), - .id_t ( axi_out_id_t ) - ) i_ar_meta_buffer ( - .clk_i ( clk_i ), - .rst_ni ( rst_ni ), - .test_enable_i ( test_enable_i ), - .req_push_i ( ar_out_push ), - .req_valid_i ( axi_out_req_o.ar_valid ), - .req_buf_i ( ar_out_data_in ), - .req_is_atop_i ( is_atop ), - .req_atop_id_i ( aw_out_id ), // Use ID from AW channel - .req_full_o ( ar_out_full ), - .req_id_o ( ar_out_id ), - .rsp_pop_i ( ar_out_pop ), - .rsp_id_i ( axi_out_rsp_i.r.id ), - .rsp_buf_o ( ar_out_data_out ) + .IdInWidth ( AxiInIdWidth ), + .IdOutWidth ( AxiOutIdWidth ), + .axi_req_t ( axi_in_req_t ), + .axi_rsp_t ( axi_in_rsp_t ) + ) i_floo_meta_buffer ( + .clk_i, + .rst_ni, + .test_enable_i, + .axi_req_i ( axi_meta_buf_req_in ), + .axi_rsp_o ( axi_meta_buf_rsp_out ), + .axi_req_o ( axi_meta_buf_req_out ), + .axi_rsp_i ( axi_meta_buf_rsp_in ), + .aw_buf_i ( aw_out_data_in ), + .ar_buf_i ( ar_out_data_in ), + .r_buf_o ( ar_out_data_out ), + .b_buf_o ( aw_out_data_out ) ); - always_comb begin - // Assign the outgoing AX an unique ID - axi_aw_id_mod = axi_unpack_aw; - axi_ar_id_mod = axi_unpack_ar; - axi_aw_id_mod.id = aw_out_id; - axi_ar_id_mod.id = ar_out_id; - end - // Registers `FF(b_rob_pending_q, b_rob_valid_out && !b_rob_ready_in && !is_atop_b_rsp, '0) `FF(r_rob_pending_q, r_rob_valid_out && !r_rob_ready_in && !is_atop_r_rsp, '0) diff --git a/src/floo_meta_buffer.sv b/src/floo_meta_buffer.sv index dc0a782a..27edf506 100644 --- a/src/floo_meta_buffer.sv +++ b/src/floo_meta_buffer.sv @@ -17,119 +17,192 @@ module floo_meta_buffer #( parameter bit AtopSupport = 1'b1, /// Number of outstanding atomic requests parameter int MaxAtomicTxns = 32'd1, - /// External Atomic ID - parameter bit ExtAtomicId = 1'b0, /// Information to be buffered for responses parameter type buf_t = logic, - /// ID type for outgoing requests - parameter type id_t = logic, + /// ID width of incoming requests + parameter int IdInWidth = 32'd4, + /// ID width of outgoing requests + parameter int IdOutWidth = 32'd2, + /// AXI request channel + parameter type axi_req_t = logic, + /// AXI response channel + parameter type axi_rsp_t = logic, + /// ID type for incoming requests + localparam type id_in_t = logic[IdInWidth-1:0], + /// ID type for outgoing responses + localparam type id_out_t = logic[IdOutWidth-1:0], /// Constant ID for non-atomic requests - localparam id_t NonAtomicId = '1 + localparam id_out_t NonAtomicId = '1 ) ( input logic clk_i, input logic rst_ni, input logic test_enable_i, - input logic req_push_i, - input logic req_valid_i, - input buf_t req_buf_i, - input logic req_is_atop_i, - input id_t req_atop_id_i, - output logic req_full_o, - output id_t req_id_o, - input logic rsp_pop_i, - input id_t rsp_id_i, - output buf_t rsp_buf_o + input axi_req_t axi_req_i, + output axi_rsp_t axi_rsp_o, + output axi_req_t axi_req_o, + input axi_rsp_t axi_rsp_i, + input buf_t aw_buf_i, + input buf_t ar_buf_i, + output buf_t r_buf_o, + output buf_t b_buf_o ); - buf_t no_atop_buf_out; - logic no_atop_buf_full; - logic rsp_is_atop; + logic ar_no_atop_buf_full, aw_no_atop_buf_full; + logic ar_no_atop_push, aw_no_atop_push; + logic ar_no_atop_pop, aw_no_atop_pop; + logic is_atop_r_rsp, is_atop_b_rsp; + logic is_atop_aw, atop_has_r_rsp; - assign rsp_is_atop = AtopSupport && (rsp_id_i != NonAtomicId); + buf_t no_atop_r_buf, no_atop_b_buf; + buf_t [MaxAtomicTxns-1:0] atop_r_buf, atop_b_buf; fifo_v3 #( .FALL_THROUGH ( 1'b0 ), .DEPTH ( MaxTxns ), .dtype ( buf_t ) - ) i_no_atop_fifo ( + ) i_ar_no_atop_fifo ( .clk_i, .rst_ni, - .flush_i ( 1'b0 ), - .testmode_i ( test_enable_i ), - .full_o ( no_atop_buf_full ), - .empty_o ( ), - .usage_o ( ), - .data_i ( req_buf_i ), - .push_i ( req_push_i && !req_is_atop_i ), - .data_o ( no_atop_buf_out ), - .pop_i ( rsp_pop_i && !rsp_is_atop ) + .flush_i ( 1'b0 ), + .testmode_i ( test_enable_i ), + .full_o ( ar_no_atop_buf_full ), + .empty_o ( ), + .usage_o ( ), + .data_i ( ar_buf_i ), + .push_i ( ar_no_atop_push ), + .data_o ( no_atop_r_buf ), + .pop_i ( ar_no_atop_pop ) ); + fifo_v3 #( + .FALL_THROUGH ( 1'b0 ), + .DEPTH ( MaxTxns ), + .dtype ( buf_t ) + ) i_aw_no_atop_fifo ( + .clk_i, + .rst_ni, + .flush_i ( 1'b0 ), + .testmode_i ( test_enable_i ), + .full_o ( aw_no_atop_buf_full ), + .empty_o ( ), + .usage_o ( ), + .data_i ( aw_buf_i ), + .push_i ( aw_no_atop_push ), + .data_o ( no_atop_b_buf ), + .pop_i ( aw_no_atop_pop ) + ); + + // Non-atomic AR's + assign ar_no_atop_push = axi_req_o.ar_valid && axi_rsp_i.ar_ready; + assign ar_no_atop_pop = axi_rsp_o.r_valid && axi_req_i.r_ready && axi_rsp_o.r.last && + !is_atop_r_rsp; + // Non-atomic AW's + assign is_atop_aw = axi_req_i.aw_valid && axi_req_i.aw.atop[5:4] != axi_pkg::ATOP_NONE; + assign aw_no_atop_push = axi_req_o.aw_valid && axi_rsp_i.aw_ready && !is_atop_aw; + assign aw_no_atop_pop = axi_rsp_o.b_valid && axi_req_i.b_ready && !is_atop_b_rsp; + + assign is_atop_r_rsp = axi_rsp_i.r_valid && axi_rsp_i.r.id != NonAtomicId; + assign is_atop_b_rsp = axi_rsp_i.b_valid && axi_rsp_i.b.id != NonAtomicId; + `ASSERT(NoAtopSupport, !(!AtopSupport && is_atop_aw), + "Atomics not supported, but atomic request received!") + + assign r_buf_o = (is_atop_r_rsp && AtopSupport)? atop_r_buf[axi_rsp_i.r.id] : no_atop_r_buf; + assign b_buf_o = (is_atop_b_rsp && AtopSupport)? atop_b_buf[axi_rsp_i.b.id] : no_atop_b_buf; + if (AtopSupport) begin : gen_atop_support - logic [MaxAtomicTxns-1:0] atop_req_out_push; - logic [MaxAtomicTxns-1:0] atop_req_out_pop; - logic [MaxAtomicTxns-1:0] atop_req_out_full; - logic [MaxAtomicTxns-1:0] atop_req_out_empty; - buf_t [MaxAtomicTxns-1:0] atop_data_out; + logic [MaxAtomicTxns-1:0] ar_atop_reg_full, aw_atop_reg_full; + logic [MaxAtomicTxns-1:0] ar_atop_reg_empty, aw_atop_reg_empty; + logic [MaxAtomicTxns-1:0] ar_atop_reg_push, aw_atop_reg_push; + logic [MaxAtomicTxns-1:0] ar_atop_reg_pop, aw_atop_reg_pop; + logic [MaxAtomicTxns-1:0] available_atop_ids; + logic no_atop_id_available; - id_t req_atop_id; + assign atop_has_r_rsp = axi_req_i.aw.atop[axi_pkg::ATOP_R_RESP]; + assign available_atop_ids = ar_atop_reg_empty & aw_atop_reg_empty; + assign no_atop_id_available = (available_atop_ids == '0); + stream_register #( + .T(buf_t) + ) i_ar_atop_regs [MaxAtomicTxns-1:0] ( + .clk_i, + .rst_ni, + .clr_i ( '0 ), + .testmode_i ( test_enable_i ), + .valid_i ( ar_atop_reg_push ), + .ready_o ( ar_atop_reg_empty ), + .data_i ( ar_buf_i ), + .valid_o ( ar_atop_reg_full ), + .ready_i ( ar_atop_reg_pop ), + .data_o ( atop_r_buf ) + ); stream_register #( .T(buf_t) - ) i_atop_regs [MaxAtomicTxns-1:0] ( + ) i_aw_atop_regs [MaxAtomicTxns-1:0] ( .clk_i, .rst_ni, - .clr_i ( '0 ), - .testmode_i ( test_enable_i ), - .valid_i ( atop_req_out_push ), - .ready_o ( atop_req_out_empty ), - .data_i ( req_buf_i ), - .valid_o ( atop_req_out_full ), - .ready_i ( atop_req_out_pop ), - .data_o ( atop_data_out ) + .clr_i ( '0 ), + .testmode_i ( test_enable_i ), + .valid_i ( aw_atop_reg_push ), + .ready_o ( aw_atop_reg_empty ), + .data_i ( aw_buf_i ), + .valid_o ( aw_atop_reg_full ), + .ready_i ( aw_atop_reg_pop ), + .data_o ( atop_b_buf ) ); - if (ExtAtomicId) begin : gen_ext_atop_id - // Atomics need to register an r response with the same ID - // as the B response. The ID is given by the AW buffer from externally. - assign req_atop_id = req_atop_id_i; - end else begin : gen_atop_id - typedef logic [cf_math_pkg::idx_width(MaxAtomicTxns)-1:0] lzc_cnt_t; - lzc_cnt_t lzc_cnt, lzc_cnt_q; - logic [MaxAtomicTxns-1:0] next_free_slots; - assign next_free_slots = ~(atop_req_out_full | atop_req_out_push) | atop_req_out_pop; - lzc #( - .WIDTH (MaxAtomicTxns) - ) i_lzc ( - .in_i ( next_free_slots ), - .cnt_o ( lzc_cnt ), - .empty_o ( ) - ); - // Next free slot needs to be registered to have a stable ID at the AXI interface - assign req_atop_id = lzc_cnt_q; - `FFL(lzc_cnt_q, lzc_cnt, req_push_i && req_is_atop_i || !req_valid_i, '0, clk_i, rst_ni) - end + typedef logic [cf_math_pkg::idx_width(MaxAtomicTxns)-1:0] atop_req_id_t; + atop_req_id_t lzc_cnt_q, lzc_cnt_d; + atop_req_id_t atop_req_id; + logic atop_req_pending_q, atop_req_pending_d; + + lzc #( + .WIDTH (MaxAtomicTxns) + ) i_lzc ( + .in_i ( available_atop_ids ), + .cnt_o ( lzc_cnt_d ), + .empty_o ( ) + ); + + assign atop_req_id = (atop_req_pending_q)? lzc_cnt_q : lzc_cnt_d; + assign atop_req_pending_d = is_atop_aw && axi_req_o.aw_valid && !axi_rsp_i.aw_ready; + + `FF(atop_req_pending_q, atop_req_pending_d, '0) + `FFL(lzc_cnt_q, lzc_cnt_d, !atop_req_pending_q, '0) always_comb begin - atop_req_out_push = '0; - atop_req_out_pop = '0; - atop_req_out_push[req_atop_id] = req_push_i && req_is_atop_i; - atop_req_out_pop[rsp_id_i] = rsp_pop_i && rsp_is_atop; + ar_atop_reg_push = '0; + aw_atop_reg_push = '0; + ar_atop_reg_pop = '0; + aw_atop_reg_pop = '0; + ar_atop_reg_push[atop_req_id] = is_atop_aw && atop_has_r_rsp && + axi_req_o.aw_valid && axi_rsp_i.aw_ready; + aw_atop_reg_push[atop_req_id] = is_atop_aw && axi_req_o.aw_valid && axi_rsp_i.aw_ready; + ar_atop_reg_pop[axi_rsp_i.r.id] = is_atop_r_rsp && + axi_rsp_o.r_valid && axi_req_i.r_ready && axi_rsp_o.r.last; + aw_atop_reg_pop[axi_rsp_i.b.id] = is_atop_b_rsp && axi_rsp_o.b_valid && axi_req_i.b_ready; end - // Atomics: The ID is the first empty slot in the buffer - // Non-atomics: The ID is the constant `NonAtomicId` - assign req_id_o = (req_is_atop_i)? req_atop_id : NonAtomicId; - assign rsp_buf_o = (rsp_is_atop)? atop_data_out[rsp_id_i] : no_atop_buf_out; - assign req_full_o = (req_is_atop_i)? &atop_req_out_full : no_atop_buf_full; - end else begin : gen_no_atop_support - assign req_id_o = NonAtomicId; - assign rsp_buf_o = no_atop_buf_out; - assign req_full_o = no_atop_buf_full; + always_comb begin + axi_req_o = axi_req_i; + axi_rsp_o = axi_rsp_i; + // Use fixed ID for non-atomic requests and unique ID for atomic requests + axi_req_o.ar.id = NonAtomicId; + axi_req_o.aw.id = (is_atop_aw && AtopSupport)? atop_req_id : NonAtomicId; + // Use original, buffered ID again for responses + axi_rsp_o.r.id = (is_atop_r_rsp && AtopSupport)? + atop_r_buf[axi_rsp_i.r.id] : no_atop_r_buf.id; + axi_rsp_o.b.id = (is_atop_b_rsp && AtopSupport)? + atop_b_buf[axi_rsp_i.b.id] : no_atop_b_buf.id; + axi_req_o.ar_valid = axi_req_i.ar_valid && !ar_no_atop_buf_full; + axi_rsp_o.ar_ready = axi_rsp_i.ar_ready && !ar_no_atop_buf_full; + axi_req_o.aw_valid = axi_req_i.aw_valid && ((is_atop_aw && AtopSupport)? + !no_atop_id_available : !aw_no_atop_buf_full); + axi_rsp_o.aw_ready = axi_rsp_i.aw_ready && ((is_atop_aw && AtopSupport)? + !no_atop_id_available : !aw_no_atop_buf_full); + end end - `ASSERT(NoAtopSupport, !(!AtopSupport && (req_push_i && req_is_atop_i))) endmodule diff --git a/src/floo_narrow_wide_chimney.sv b/src/floo_narrow_wide_chimney.sv index 600c75f2..84fbd75b 100644 --- a/src/floo_narrow_wide_chimney.sv +++ b/src/floo_narrow_wide_chimney.sv @@ -35,16 +35,14 @@ module floo_narrow_wide_chimney parameter int unsigned NarrowMaxTxnsPerId = NarrowMaxTxns, /// Maximum number of outstanding requests per ID on the wide network parameter int unsigned WideMaxTxnsPerId = WideMaxTxns, + /// Type of the narrow reorder buffer + parameter rob_type_e NarrowRoBType = NoRoB, + /// Type of the wide reorder buffer + parameter rob_type_e WideRoBType = NoRoB, /// Capacity of the narrow reorder buffers - parameter int unsigned NarrowReorderBufferSize = 32, + parameter int unsigned NarrowReorderBufferSize = 256, /// Capacity of the wide reorder buffers - parameter int unsigned WideReorderBufferSize = 32, - /// Choice between simple or advanced narrow reorder buffers, - /// trade-off between area and performance - parameter bit NarrowRoBSimple = 1'b0, - /// Choice between simple or advanced wide reorder buffers, - /// trade-off between area and performance - parameter bit WideRoBSimple = 1'b0, + parameter int unsigned WideReorderBufferSize = 256, /// Cut timing paths of outgoing requests to the NoC parameter bit CutAx = 1'b1, /// Cut timing paths of incoming responses from the NoC @@ -58,61 +56,48 @@ module floo_narrow_wide_chimney parameter int unsigned NumRules = NumIDs, /// Type for implementation inputs and outputs parameter type sram_cfg_t = logic - ) ( - input logic clk_i, - input logic rst_ni, - input logic test_enable_i, - input sram_cfg_t sram_cfg_i, - /// AXI4 side interfaces - input axi_narrow_in_req_t axi_narrow_in_req_i, - output axi_narrow_in_rsp_t axi_narrow_in_rsp_o, - output axi_narrow_out_req_t axi_narrow_out_req_o, - input axi_narrow_out_rsp_t axi_narrow_out_rsp_i, - input axi_wide_in_req_t axi_wide_in_req_i, - output axi_wide_in_rsp_t axi_wide_in_rsp_o, - output axi_wide_out_req_t axi_wide_out_req_o, - input axi_wide_out_rsp_t axi_wide_out_rsp_i, - /// Coordinates/ID of the current tile - input xy_id_t xy_id_i, - input id_t id_i, - /// Routing table - input id_rule_t[NumRules-1:0] id_map_i, - /// Output to NoC - output floo_req_t floo_req_o, - output floo_rsp_t floo_rsp_o, - output floo_wide_t floo_wide_o, - /// Input from NoC - input floo_req_t floo_req_i, - input floo_rsp_t floo_rsp_i, - input floo_wide_t floo_wide_i - ); - - typedef logic [$clog2(NarrowReorderBufferSize)-1:0] narrow_rob_idx_t; - typedef logic [$clog2(WideReorderBufferSize)-1:0] wide_rob_idx_t; - - // AX queue - axi_narrow_in_aw_chan_t axi_narrow_aw_queue; - axi_narrow_in_ar_chan_t axi_narrow_ar_queue; - axi_wide_in_aw_chan_t axi_wide_aw_queue; - axi_wide_in_ar_chan_t axi_wide_ar_queue; - logic axi_narrow_aw_queue_valid_out, axi_narrow_aw_queue_ready_in; +) ( + input logic clk_i, + input logic rst_ni, + input logic test_enable_i, + input sram_cfg_t sram_cfg_i, + /// AXI4 side interfaces + input axi_narrow_in_req_t axi_narrow_in_req_i, + output axi_narrow_in_rsp_t axi_narrow_in_rsp_o, + output axi_narrow_out_req_t axi_narrow_out_req_o, + input axi_narrow_out_rsp_t axi_narrow_out_rsp_i, + input axi_wide_in_req_t axi_wide_in_req_i, + output axi_wide_in_rsp_t axi_wide_in_rsp_o, + output axi_wide_out_req_t axi_wide_out_req_o, + input axi_wide_out_rsp_t axi_wide_out_rsp_i, + /// Coordinates/ID of the current tile + input xy_id_t xy_id_i, + input id_t id_i, + /// Routing table + input id_rule_t[NumRules-1:0] id_map_i, + /// Output to NoC + output floo_req_t floo_req_o, + output floo_rsp_t floo_rsp_o, + output floo_wide_t floo_wide_o, + /// Input from NoC + input floo_req_t floo_req_i, + input floo_rsp_t floo_rsp_i, + input floo_wide_t floo_wide_i +); + + typedef logic [$clog2(NarrowReorderBufferSize)-1:0] narrow_rob_idx_t; + typedef logic [$clog2(WideReorderBufferSize)-1:0] wide_rob_idx_t; + + // AX queue + axi_narrow_in_aw_chan_t axi_narrow_aw_queue; + axi_narrow_in_ar_chan_t axi_narrow_ar_queue; + axi_wide_in_aw_chan_t axi_wide_aw_queue; + axi_wide_in_ar_chan_t axi_wide_ar_queue; + logic axi_narrow_aw_queue_valid_out, axi_narrow_aw_queue_ready_in; logic axi_narrow_ar_queue_valid_out, axi_narrow_ar_queue_ready_in; logic axi_wide_aw_queue_valid_out, axi_wide_aw_queue_ready_in; logic axi_wide_ar_queue_valid_out, axi_wide_ar_queue_ready_in; - axi_narrow_in_req_t axi_narrow_out_req_id_mapped; - axi_narrow_in_rsp_t axi_narrow_out_rsp_id_mapped; - axi_wide_in_req_t axi_wide_out_req_id_mapped; - axi_wide_in_rsp_t axi_wide_out_rsp_id_mapped; - `AXI_ASSIGN_REQ_STRUCT(axi_narrow_out_req_o, - axi_narrow_out_req_id_mapped) - `AXI_ASSIGN_RESP_STRUCT(axi_narrow_out_rsp_id_mapped, - axi_narrow_out_rsp_i) - `AXI_ASSIGN_REQ_STRUCT(axi_wide_out_req_o, - axi_wide_out_req_id_mapped) - `AXI_ASSIGN_RESP_STRUCT(axi_wide_out_rsp_id_mapped, - axi_wide_out_rsp_i) - floo_req_chan_t [WideAr:NarrowAw] floo_req_arb_in; floo_rsp_chan_t [WideB:NarrowB] floo_rsp_arb_in; floo_wide_chan_t [WideR:WideW] floo_wide_arb_in; @@ -134,15 +119,11 @@ module floo_narrow_wide_chimney floo_narrow_w_flit_t floo_narrow_w; floo_narrow_b_flit_t floo_narrow_b; floo_narrow_r_flit_t floo_narrow_r; - axi_narrow_in_aw_chan_t axi_narrow_aw_id_mod; - axi_narrow_in_ar_chan_t axi_narrow_ar_id_mod; floo_wide_aw_flit_t floo_wide_aw; floo_wide_ar_flit_t floo_wide_ar; floo_wide_w_flit_t floo_wide_w; floo_wide_b_flit_t floo_wide_b; floo_wide_r_flit_t floo_wide_r; - axi_wide_in_aw_chan_t axi_wide_aw_id_mod; - axi_wide_in_ar_chan_t axi_wide_ar_id_mod; // Flit arbitration typedef enum logic {SelAw, SelW} aw_w_sel_e; @@ -164,6 +145,16 @@ module floo_narrow_wide_chimney floo_rsp_generic_flit_t floo_narrow_unpack_rsp_generic; floo_wide_generic_flit_t floo_wide_unpack_generic; + // Meta Buffers + axi_narrow_in_req_t axi_narrow_meta_buf_req_in, axi_narrow_meta_buf_req_out; + axi_narrow_in_rsp_t axi_narrow_meta_buf_rsp_in, axi_narrow_meta_buf_rsp_out; + axi_wide_in_req_t axi_wide_meta_buf_req_in, axi_wide_meta_buf_req_out; + axi_wide_in_rsp_t axi_wide_meta_buf_rsp_in, axi_wide_meta_buf_rsp_out; + `AXI_ASSIGN_REQ_STRUCT(axi_narrow_out_req_o, axi_narrow_meta_buf_req_out) + `AXI_ASSIGN_RESP_STRUCT(axi_narrow_meta_buf_rsp_in, axi_narrow_out_rsp_i) + `AXI_ASSIGN_REQ_STRUCT(axi_wide_out_req_o, axi_wide_meta_buf_req_out) + `AXI_ASSIGN_RESP_STRUCT(axi_wide_meta_buf_rsp_in, axi_wide_out_rsp_i) + // ID tracking typedef struct packed { axi_narrow_in_id_t id; @@ -184,20 +175,8 @@ module floo_narrow_wide_chimney id_t [NumNarrowWideAxiChannels-1:0] dst_id; id_t src_id; - logic narrow_aw_out_push, narrow_aw_out_pop; - logic narrow_ar_out_push, narrow_ar_out_pop; - logic narrow_aw_out_full; - logic narrow_ar_out_full; - axi_narrow_out_id_t narrow_aw_out_id; - axi_narrow_out_id_t narrow_ar_out_id; narrow_id_out_buf_t narrow_aw_out_data_in, narrow_aw_out_data_out; narrow_id_out_buf_t narrow_ar_out_data_in, narrow_ar_out_data_out; - logic wide_aw_out_push, wide_aw_out_pop; - logic wide_ar_out_push, wide_ar_out_pop; - logic wide_aw_out_full; - logic wide_ar_out_full; - axi_wide_out_id_t wide_aw_out_id; - axi_wide_out_id_t wide_ar_out_id; wide_id_out_buf_t wide_aw_out_data_in, wide_aw_out_data_out; wide_id_out_buf_t wide_ar_out_data_in, wide_ar_out_data_out; @@ -377,14 +356,16 @@ module floo_narrow_wide_chimney (axi_narrow_aw_queue.atop != axi_pkg::ATOP_NONE))) end - floo_simple_rob #( + floo_rob_wrapper #( + .RoBType ( NarrowRoBType ), .ReorderBufferSize ( NarrowReorderBufferSize ), .MaxRoTxnsPerId ( NarrowMaxTxnsPerId ), .OnlyMetaData ( 1'b1 ), .ax_len_t ( axi_pkg::len_t ), + .ax_id_t ( axi_narrow_in_id_t ), .rsp_chan_t ( axi_narrow_in_b_chan_t ), .rsp_meta_t ( axi_narrow_in_b_chan_t ), - .rob_idx_t ( narrow_rob_idx_t ), + .rob_idx_t ( rob_idx_t ), .dest_t ( id_t ), .sram_cfg_t ( sram_cfg_t ) ) i_narrow_b_rob ( @@ -394,6 +375,7 @@ module floo_narrow_wide_chimney .ax_valid_i ( narrow_aw_rob_valid_in ), .ax_ready_o ( narrow_aw_rob_ready_out ), .ax_len_i ( axi_narrow_aw_queue.len ), + .ax_id_i ( axi_narrow_aw_queue.id ), .ax_dest_i ( dst_id[NarrowAw] ), .ax_valid_o ( narrow_aw_rob_valid_out ), .ax_ready_i ( narrow_aw_rob_ready_in ), @@ -417,11 +399,13 @@ module floo_narrow_wide_chimney assign wide_b_rob_rob_idx = floo_rsp_in.wide_b.hdr.rob_idx; assign wide_b_rob_last = floo_rsp_in.wide_b.hdr.last; - floo_simple_rob #( + floo_rob_wrapper #( + .RoBType ( WideRoBType ), .ReorderBufferSize ( WideReorderBufferSize ), .MaxRoTxnsPerId ( WideMaxTxnsPerId ), .OnlyMetaData ( 1'b1 ), .ax_len_t ( axi_pkg::len_t ), + .ax_id_t ( axi_wide_in_id_t ), .rsp_chan_t ( axi_wide_in_b_chan_t ), .rsp_meta_t ( axi_wide_in_b_chan_t ), .rob_idx_t ( narrow_rob_idx_t ), @@ -434,6 +418,7 @@ module floo_narrow_wide_chimney .ax_valid_i ( axi_wide_aw_queue_valid_out ), .ax_ready_o ( axi_wide_aw_queue_ready_in ), .ax_len_i ( axi_wide_aw_queue.len ), + .ax_id_i ( axi_wide_aw_queue.id ), .ax_dest_i ( dst_id[WideAw] ), .ax_valid_o ( wide_aw_rob_valid_out ), .ax_ready_i ( wide_aw_rob_ready_in ), @@ -471,77 +456,42 @@ module floo_narrow_wide_chimney assign narrow_r_rob_rob_idx = floo_rsp_in.narrow_r.hdr.rob_idx; assign narrow_r_rob_last = floo_rsp_in.narrow_r.hdr.last; - if (NarrowRoBSimple) begin : gen_narrow_simple_rob - floo_simple_rob #( - .ReorderBufferSize ( NarrowReorderBufferSize ), - .MaxRoTxnsPerId ( NarrowMaxTxnsPerId ), - .OnlyMetaData ( 1'b0 ), - .ax_len_t ( axi_pkg::len_t ), - .rsp_chan_t ( axi_narrow_in_r_chan_t ), - .rsp_data_t ( axi_narrow_in_data_t ), - .rsp_meta_t ( narrow_meta_t ), - .rob_idx_t ( narrow_rob_idx_t ), - .dest_t ( id_t ), - .sram_cfg_t ( sram_cfg_t ) - ) i_narrow_r_rob ( - .clk_i, - .rst_ni, - .sram_cfg_i, - .ax_valid_i ( axi_narrow_ar_queue_valid_out ), - .ax_ready_o ( axi_narrow_ar_queue_ready_in ), - .ax_len_i ( axi_narrow_ar_queue.len ), - .ax_dest_i ( dst_id[NarrowAr] ), - .ax_valid_o ( narrow_ar_rob_valid_out ), - .ax_ready_i ( narrow_ar_rob_ready_in ), - .ax_rob_req_o ( narrow_ar_rob_req_out ), - .ax_rob_idx_o ( narrow_ar_rob_idx_out ), - .rsp_valid_i ( narrow_r_rob_valid_in ), - .rsp_ready_o ( narrow_r_rob_ready_out ), - .rsp_i ( axi_narrow_r_rob_in ), - .rsp_rob_req_i ( narrow_r_rob_rob_req ), - .rsp_rob_idx_i ( narrow_r_rob_rob_idx ), - .rsp_last_i ( narrow_r_rob_last ), - .rsp_valid_o ( narrow_r_rob_valid_out ), - .rsp_ready_i ( narrow_r_rob_ready_in ), - .rsp_o ( axi_narrow_r_rob_out ) - ); - end else begin : gen_narrow_rob - floo_rob #( - .ReorderBufferSize ( NarrowReorderBufferSize ), - .MaxRoTxnsPerId ( NarrowMaxTxnsPerId ), - .OnlyMetaData ( 1'b0 ), - .ax_len_t ( axi_pkg::len_t ), - .ax_id_t ( axi_narrow_in_id_t ), - .rsp_chan_t ( axi_narrow_in_r_chan_t ), - .rsp_data_t ( axi_narrow_in_data_t ), - .rsp_meta_t ( narrow_meta_t ), - .rob_idx_t ( narrow_rob_idx_t ), - .dest_t ( id_t ), - .sram_cfg_t ( sram_cfg_t ) - ) i_narrow_r_rob ( - .clk_i, - .rst_ni, - .sram_cfg_i, - .ax_valid_i ( axi_narrow_ar_queue_valid_out ), - .ax_ready_o ( axi_narrow_ar_queue_ready_in ), - .ax_len_i ( axi_narrow_ar_queue.len ), - .ax_id_i ( axi_narrow_ar_queue.id ), - .ax_dest_i ( dst_id[NarrowAr] ), - .ax_valid_o ( narrow_ar_rob_valid_out ), - .ax_ready_i ( narrow_ar_rob_ready_in ), - .ax_rob_req_o ( narrow_ar_rob_req_out ), - .ax_rob_idx_o ( narrow_ar_rob_idx_out ), - .rsp_valid_i ( narrow_r_rob_valid_in ), - .rsp_ready_o ( narrow_r_rob_ready_out ), - .rsp_i ( axi_narrow_r_rob_in ), - .rsp_rob_req_i ( narrow_r_rob_rob_req ), - .rsp_rob_idx_i ( narrow_r_rob_rob_idx ), - .rsp_last_i ( narrow_r_rob_last ), - .rsp_valid_o ( narrow_r_rob_valid_out ), - .rsp_ready_i ( narrow_r_rob_ready_in ), - .rsp_o ( axi_narrow_r_rob_out ) - ); - end + floo_rob_wrapper #( + .RoBType ( NarrowRoBType ), + .ReorderBufferSize ( NarrowReorderBufferSize ), + .MaxRoTxnsPerId ( NarrowMaxTxnsPerId ), + .OnlyMetaData ( 1'b0 ), + .ax_len_t ( axi_pkg::len_t ), + .ax_id_t ( axi_narrow_in_id_t ), + .rsp_chan_t ( axi_narrow_in_r_chan_t ), + .rsp_data_t ( axi_narrow_in_data_t ), + .rsp_meta_t ( narrow_meta_t ), + .rob_idx_t ( narrow_rob_idx_t ), + .dest_t ( id_t ), + .sram_cfg_t ( sram_cfg_t ) + ) i_narrow_r_rob ( + .clk_i, + .rst_ni, + .sram_cfg_i, + .ax_valid_i ( axi_narrow_ar_queue_valid_out ), + .ax_ready_o ( axi_narrow_ar_queue_ready_in ), + .ax_len_i ( axi_narrow_ar_queue.len ), + .ax_id_i ( axi_narrow_ar_queue.id ), + .ax_dest_i ( dst_id[NarrowAr] ), + .ax_valid_o ( narrow_ar_rob_valid_out ), + .ax_ready_i ( narrow_ar_rob_ready_in ), + .ax_rob_req_o ( narrow_ar_rob_req_out ), + .ax_rob_idx_o ( narrow_ar_rob_idx_out ), + .rsp_valid_i ( narrow_r_rob_valid_in ), + .rsp_ready_o ( narrow_r_rob_ready_out ), + .rsp_i ( axi_narrow_r_rob_in ), + .rsp_rob_req_i ( narrow_r_rob_rob_req ), + .rsp_rob_idx_i ( narrow_r_rob_rob_idx ), + .rsp_last_i ( narrow_r_rob_last ), + .rsp_valid_o ( narrow_r_rob_valid_out ), + .rsp_ready_i ( narrow_r_rob_ready_in ), + .rsp_o ( axi_narrow_r_rob_out ) + ); logic wide_r_rob_rob_req; logic wide_r_rob_last; @@ -550,77 +500,42 @@ module floo_narrow_wide_chimney assign wide_r_rob_rob_idx = floo_wide_in.wide_r.hdr.rob_idx; assign wide_r_rob_last = floo_wide_in.wide_r.hdr.last; - if (WideRoBSimple) begin : gen_wide_simple_rob - floo_simple_rob #( - .ReorderBufferSize ( WideReorderBufferSize ), - .MaxRoTxnsPerId ( WideMaxTxnsPerId ), - .OnlyMetaData ( 1'b0 ), - .ax_len_t ( axi_pkg::len_t ), - .rsp_chan_t ( axi_wide_in_r_chan_t ), - .rsp_data_t ( axi_wide_in_data_t ), - .rsp_meta_t ( wide_meta_t ), - .rob_idx_t ( wide_rob_idx_t ), - .dest_t ( id_t ), - .sram_cfg_t ( sram_cfg_t ) - ) i_wide_r_rob ( - .clk_i, - .rst_ni, - .sram_cfg_i, - .ax_valid_i ( axi_wide_ar_queue_valid_out ), - .ax_ready_o ( axi_wide_ar_queue_ready_in ), - .ax_len_i ( axi_wide_ar_queue.len ), - .ax_dest_i ( dst_id[WideAr] ), - .ax_valid_o ( wide_ar_rob_valid_out ), - .ax_ready_i ( wide_ar_rob_ready_in ), - .ax_rob_req_o ( wide_ar_rob_req_out ), - .ax_rob_idx_o ( wide_ar_rob_idx_out ), - .rsp_valid_i ( wide_r_rob_valid_in ), - .rsp_ready_o ( wide_r_rob_ready_out ), - .rsp_i ( wide_r_rob_in ), - .rsp_rob_req_i ( wide_r_rob_rob_req ), - .rsp_rob_idx_i ( wide_r_rob_rob_idx ), - .rsp_last_i ( wide_r_rob_last ), - .rsp_valid_o ( wide_r_rob_valid_out ), - .rsp_ready_i ( wide_r_rob_ready_in ), - .rsp_o ( wide_r_rob_out ) - ); - end else begin : gen_wide_rob - floo_rob #( - .ReorderBufferSize ( WideReorderBufferSize ), - .MaxRoTxnsPerId ( WideMaxTxnsPerId ), - .OnlyMetaData ( 1'b0 ), - .ax_len_t ( axi_pkg::len_t ), - .ax_id_t ( axi_wide_in_id_t ), - .rsp_chan_t ( axi_wide_in_r_chan_t ), - .rsp_data_t ( axi_wide_in_data_t ), - .rsp_meta_t ( wide_meta_t ), - .rob_idx_t ( wide_rob_idx_t ), - .dest_t ( id_t ), - .sram_cfg_t ( sram_cfg_t ) - ) i_wide_r_rob ( - .clk_i, - .rst_ni, - .sram_cfg_i, - .ax_valid_i ( axi_wide_ar_queue_valid_out ), - .ax_ready_o ( axi_wide_ar_queue_ready_in ), - .ax_len_i ( axi_wide_ar_queue.len ), - .ax_id_i ( axi_wide_ar_queue.id ), - .ax_dest_i ( dst_id[WideAr] ), - .ax_valid_o ( wide_ar_rob_valid_out ), - .ax_ready_i ( wide_ar_rob_ready_in ), - .ax_rob_req_o ( wide_ar_rob_req_out ), - .ax_rob_idx_o ( wide_ar_rob_idx_out ), - .rsp_valid_i ( wide_r_rob_valid_in ), - .rsp_ready_o ( wide_r_rob_ready_out ), - .rsp_i ( axi_wide_r_rob_in ), - .rsp_rob_req_i ( wide_r_rob_rob_req ), - .rsp_rob_idx_i ( wide_r_rob_rob_idx ), - .rsp_last_i ( wide_r_rob_last ), - .rsp_valid_o ( wide_r_rob_valid_out ), - .rsp_ready_i ( wide_r_rob_ready_in ), - .rsp_o ( axi_wide_r_rob_out ) - ); - end + floo_rob_wrapper #( + .RoBType ( WideRoBType ), + .ReorderBufferSize ( WideReorderBufferSize ), + .MaxRoTxnsPerId ( WideMaxTxnsPerId ), + .OnlyMetaData ( 1'b0 ), + .ax_len_t ( axi_pkg::len_t ), + .ax_id_t ( axi_wide_in_id_t ), + .rsp_chan_t ( axi_wide_in_r_chan_t ), + .rsp_data_t ( axi_wide_in_data_t ), + .rsp_meta_t ( wide_meta_t ), + .rob_idx_t ( wide_rob_idx_t ), + .dest_t ( id_t ), + .sram_cfg_t ( sram_cfg_t ) + ) i_wide_r_rob ( + .clk_i, + .rst_ni, + .sram_cfg_i, + .ax_valid_i ( axi_wide_ar_queue_valid_out ), + .ax_ready_o ( axi_wide_ar_queue_ready_in ), + .ax_len_i ( axi_wide_ar_queue.len ), + .ax_id_i ( axi_wide_ar_queue.id ), + .ax_dest_i ( dst_id[WideAr] ), + .ax_valid_o ( wide_ar_rob_valid_out ), + .ax_ready_i ( wide_ar_rob_ready_in ), + .ax_rob_req_o ( wide_ar_rob_req_out ), + .ax_rob_idx_o ( wide_ar_rob_idx_out ), + .rsp_valid_i ( wide_r_rob_valid_in ), + .rsp_ready_o ( wide_r_rob_ready_out ), + .rsp_i ( axi_wide_r_rob_in ), + .rsp_rob_req_i ( wide_r_rob_rob_req ), + .rsp_rob_idx_i ( wide_r_rob_rob_idx ), + .rsp_last_i ( wide_r_rob_last ), + .rsp_valid_o ( wide_r_rob_valid_out ), + .rsp_ready_i ( wide_r_rob_ready_in ), + .rsp_o ( axi_wide_r_rob_out ) + ); ///////////////// // ROUTING // @@ -747,7 +662,7 @@ module floo_narrow_wide_chimney floo_narrow_b.hdr.last = 1'b1; floo_narrow_b.hdr.axi_ch = NarrowB; floo_narrow_b.hdr.atop = narrow_aw_out_data_out.atop; - floo_narrow_b.b = axi_narrow_out_rsp_id_mapped.b; + floo_narrow_b.b = axi_narrow_meta_buf_rsp_out.b; floo_narrow_b.b.id = narrow_aw_out_data_out.id; end @@ -760,7 +675,7 @@ module floo_narrow_wide_chimney floo_narrow_r.hdr.axi_ch = NarrowR; floo_narrow_r.hdr.last = axi_narrow_out_rsp_i.r.last; floo_narrow_r.hdr.atop = narrow_ar_out_data_out.atop; - floo_narrow_r.r = axi_narrow_out_rsp_id_mapped.r; + floo_narrow_r.r = axi_narrow_meta_buf_rsp_out.r; floo_narrow_r.r.id = narrow_ar_out_data_out.id; end @@ -805,7 +720,7 @@ module floo_narrow_wide_chimney floo_wide_b.hdr.src_id = src_id; floo_wide_b.hdr.last = 1'b1; floo_wide_b.hdr.axi_ch = WideB; - floo_wide_b.b = axi_wide_out_rsp_id_mapped.b; + floo_wide_b.b = axi_wide_meta_buf_rsp_out.b; floo_wide_b.b.id = wide_aw_out_data_out.id; end @@ -817,7 +732,7 @@ module floo_narrow_wide_chimney floo_wide_r.hdr.src_id = src_id; floo_wide_r.hdr.axi_ch = WideR; floo_wide_r.hdr.last = axi_wide_out_rsp_i.r.last; - floo_wide_r.r = axi_wide_out_rsp_id_mapped.r; + floo_wide_r.r = axi_wide_meta_buf_rsp_out.r; floo_wide_r.r.id = wide_ar_out_data_out.id; end @@ -852,27 +767,23 @@ module floo_narrow_wide_chimney assign floo_req_arb_req_in[WideAw] = (wide_aw_w_sel_q == SelAw) && wide_aw_rob_valid_out; assign floo_req_arb_req_in[WideAr] = wide_ar_rob_valid_out; - assign floo_rsp_arb_req_in[NarrowB] = axi_narrow_out_rsp_i.b_valid; - assign floo_rsp_arb_req_in[NarrowR] = axi_narrow_out_rsp_i.r_valid; - assign floo_rsp_arb_req_in[WideB] = axi_wide_out_rsp_i.b_valid; + assign floo_rsp_arb_req_in[NarrowB] = axi_narrow_meta_buf_rsp_out.b_valid; + assign floo_rsp_arb_req_in[NarrowR] = axi_narrow_meta_buf_rsp_out.r_valid; + assign floo_rsp_arb_req_in[WideB] = axi_wide_meta_buf_rsp_out.b_valid; assign floo_wide_arb_req_in[WideW] = (wide_aw_w_sel_q == SelW) && axi_wide_in_req_i.w_valid; - assign floo_wide_arb_req_in[WideR] = axi_wide_out_rsp_i.r_valid; + assign floo_wide_arb_req_in[WideR] = axi_wide_meta_buf_rsp_out.r_valid; assign narrow_aw_rob_ready_in = floo_req_arb_gnt_out[NarrowAw] && (narrow_aw_w_sel_q == SelAw); assign axi_narrow_in_rsp_o.w_ready = floo_req_arb_gnt_out[NarrowW] && (narrow_aw_w_sel_q == SelW); assign narrow_ar_rob_ready_in = floo_req_arb_gnt_out[NarrowAr]; - assign axi_narrow_out_req_id_mapped.b_ready = floo_rsp_arb_gnt_out[NarrowB]; - assign axi_narrow_out_req_id_mapped.r_ready = floo_rsp_arb_gnt_out[NarrowR]; assign wide_aw_rob_ready_in = floo_req_arb_gnt_out[WideAw] && (wide_aw_w_sel_q == SelAw); assign axi_wide_in_rsp_o.w_ready = floo_wide_arb_gnt_out[WideW] && (wide_aw_w_sel_q == SelW); assign wide_ar_rob_ready_in = floo_req_arb_gnt_out[WideAr]; - assign axi_wide_out_req_id_mapped.b_ready = floo_rsp_arb_gnt_out[WideB]; - assign axi_wide_out_req_id_mapped.r_ready = floo_wide_arb_gnt_out[WideR]; assign floo_req_arb_in[NarrowAw].narrow_aw = floo_narrow_aw; assign floo_req_arb_in[NarrowW].narrow_w = floo_narrow_w; @@ -982,39 +893,55 @@ module floo_narrow_wide_chimney assign axi_valid_in[WideR] = floo_wide_in_valid && (floo_wide_unpack_generic.hdr.axi_ch == WideR); - assign axi_ready_out[NarrowAw] = axi_narrow_out_rsp_i.aw_ready && !narrow_aw_out_full; - assign axi_ready_out[NarrowW] = axi_narrow_out_rsp_i.w_ready; - assign axi_ready_out[NarrowAr] = axi_narrow_out_rsp_i.ar_ready && !narrow_ar_out_full; + assign axi_ready_out[NarrowAw] = axi_narrow_meta_buf_rsp_out.aw_ready; + assign axi_ready_out[NarrowW] = axi_narrow_meta_buf_rsp_out.w_ready; + assign axi_ready_out[NarrowAr] = axi_narrow_meta_buf_rsp_out.ar_ready; assign axi_ready_out[NarrowB] = narrow_b_rob_ready_out || b_sel_atop && axi_narrow_in_req_i.b_ready; assign axi_ready_out[NarrowR] = narrow_r_rob_ready_out || r_sel_atop && axi_narrow_in_req_i.r_ready; - assign axi_ready_out[WideAw] = axi_wide_out_rsp_i.aw_ready && !wide_aw_out_full; - assign axi_ready_out[WideW] = axi_wide_out_rsp_i.w_ready; - assign axi_ready_out[WideAr] = axi_wide_out_rsp_i.ar_ready&& !wide_ar_out_full; + assign axi_ready_out[WideAw] = axi_wide_meta_buf_rsp_out.aw_ready; + assign axi_ready_out[WideW] = axi_wide_meta_buf_rsp_out.w_ready; + assign axi_ready_out[WideAr] = axi_wide_meta_buf_rsp_out.ar_ready; assign axi_ready_out[WideB] = wide_b_rob_ready_out; assign axi_ready_out[WideR] = wide_r_rob_ready_out; assign floo_req_out_ready = axi_ready_out[floo_narrow_unpack_req_generic.hdr.axi_ch]; assign floo_rsp_out_ready = axi_ready_out[floo_narrow_unpack_rsp_generic.hdr.axi_ch]; - assign floo_wide_out_ready = axi_ready_out[floo_wide_unpack_generic.hdr.axi_ch]; + assign floo_wide_out_ready = axi_ready_out[floo_wide_unpack_generic.hdr.axi_ch]; ///////////////////////////// // AXI req/rsp generation // //////////////////////////// - assign axi_narrow_out_req_id_mapped.aw_valid = axi_valid_in[NarrowAw] && !narrow_aw_out_full; - assign axi_narrow_out_req_id_mapped.w_valid = axi_valid_in[NarrowW]; - assign axi_narrow_out_req_id_mapped.ar_valid = axi_valid_in[NarrowAr] && !narrow_ar_out_full; + assign axi_narrow_meta_buf_req_in ='{ + aw : axi_narrow_unpack_aw, + aw_valid : axi_valid_in[NarrowAw], + w : axi_narrow_unpack_w, + w_valid : axi_valid_in[NarrowW], + b_ready : floo_rsp_arb_gnt_out[NarrowB], + ar : axi_narrow_unpack_ar, + ar_valid : axi_valid_in[NarrowAr], + r_ready : floo_rsp_arb_gnt_out[NarrowR] + }; + + assign axi_wide_meta_buf_req_in ='{ + aw : axi_wide_unpack_aw, + aw_valid : axi_valid_in[WideAw], + w : axi_wide_unpack_w, + w_valid : axi_valid_in[WideW], + b_ready : floo_rsp_arb_gnt_out[WideB], + ar : axi_wide_unpack_ar, + ar_valid : axi_valid_in[WideAr], + r_ready : floo_wide_arb_gnt_out[WideR] + }; + assign narrow_b_rob_valid_in = axi_valid_in[NarrowB] && !is_atop_b_rsp; assign narrow_r_rob_valid_in = axi_valid_in[NarrowR] && !is_atop_r_rsp; assign axi_narrow_in_rsp_o.b_valid = narrow_b_rob_valid_out || is_atop_b_rsp; assign axi_narrow_in_rsp_o.r_valid = narrow_r_rob_valid_out || is_atop_r_rsp; assign narrow_b_rob_ready_in = axi_narrow_in_req_i.b_ready && !b_sel_atop; assign narrow_r_rob_ready_in = axi_narrow_in_req_i.r_ready && !r_sel_atop; - assign axi_wide_out_req_id_mapped.aw_valid = axi_valid_in[WideAw] && !wide_aw_out_full; - assign axi_wide_out_req_id_mapped.w_valid = axi_valid_in[WideW]; - assign axi_wide_out_req_id_mapped.ar_valid = axi_valid_in[WideAr] && !wide_ar_out_full; assign wide_b_rob_valid_in = axi_valid_in[WideB]; assign wide_r_rob_valid_in = axi_valid_in[WideR]; assign axi_wide_in_rsp_o.b_valid = wide_b_rob_valid_out; @@ -1022,18 +949,12 @@ module floo_narrow_wide_chimney assign wide_b_rob_ready_in = axi_wide_in_req_i.b_ready; assign wide_r_rob_ready_in = axi_wide_in_req_i.r_ready; - assign axi_narrow_out_req_id_mapped.aw = axi_narrow_aw_id_mod; - assign axi_narrow_out_req_id_mapped.w = axi_narrow_unpack_w; - assign axi_narrow_out_req_id_mapped.ar = axi_narrow_ar_id_mod; assign axi_narrow_b_rob_in = axi_narrow_unpack_b; assign axi_narrow_r_rob_in = axi_narrow_unpack_r; assign axi_narrow_in_rsp_o.b = (b_sel_atop)? axi_narrow_unpack_b : axi_narrow_b_rob_out; assign axi_narrow_in_rsp_o.r = (r_sel_atop)? axi_narrow_unpack_r : axi_narrow_r_rob_out; - assign axi_wide_out_req_id_mapped.aw = axi_wide_aw_id_mod; - assign axi_wide_out_req_id_mapped.w = axi_wide_unpack_w; - assign axi_wide_out_req_id_mapped.ar = axi_wide_ar_id_mod; assign axi_wide_b_rob_in = axi_wide_unpack_b; assign axi_wide_r_rob_in = axi_wide_unpack_r; assign axi_wide_in_rsp_o.b = axi_wide_b_rob_out; @@ -1045,21 +966,6 @@ module floo_narrow_wide_chimney assign atop_has_r_rsp = AtopSupport && axi_valid_in[NarrowAw] && axi_narrow_unpack_aw.atop[axi_pkg::ATOP_R_RESP]; - assign narrow_aw_out_push = axi_narrow_out_req_o.aw_valid && axi_narrow_out_rsp_i.aw_ready; - assign narrow_ar_out_push = axi_narrow_out_req_o.ar_valid && axi_narrow_out_rsp_i.ar_ready || - axi_narrow_out_req_o.aw_valid && axi_narrow_out_rsp_i.aw_ready && - is_atop && atop_has_r_rsp; - assign narrow_aw_out_pop = axi_narrow_out_rsp_i.b_valid && axi_narrow_out_req_o.b_ready; - assign narrow_ar_out_pop = axi_narrow_out_rsp_i.r_valid && axi_narrow_out_req_o.r_ready & - axi_narrow_out_rsp_i.r.last; - - assign wide_aw_out_push = axi_wide_out_req_o.aw_valid && axi_wide_out_rsp_i.aw_ready; - assign wide_ar_out_push = axi_wide_out_req_o.ar_valid && axi_wide_out_rsp_i.ar_ready; - assign wide_aw_out_pop = axi_wide_out_rsp_i.b_valid && axi_wide_out_req_o.b_ready; - assign wide_ar_out_pop = axi_wide_out_rsp_i.r_valid && axi_wide_out_req_o.r_ready && - axi_wide_out_rsp_i.r.last; - - assign narrow_aw_out_data_in = '{ id: axi_narrow_unpack_aw.id, rob_req: floo_narrow_unpack_req_generic.hdr.rob_req, @@ -1068,7 +974,7 @@ module floo_narrow_wide_chimney atop: floo_narrow_unpack_req_generic.hdr.atop }; assign narrow_ar_out_data_in = '{ - id: axi_narrow_unpack_ar.id, + id: (is_atop && atop_has_r_rsp)? axi_narrow_unpack_aw.id : axi_narrow_unpack_ar.id, rob_req: floo_narrow_unpack_req_generic.hdr.rob_req, rob_idx: floo_narrow_unpack_req_generic.hdr.rob_idx, src_id: floo_narrow_unpack_req_generic.hdr.src_id, @@ -1092,101 +998,47 @@ module floo_narrow_wide_chimney .AtopSupport ( AtopSupport ), .MaxAtomicTxns ( MaxAtomicTxns ), .buf_t ( narrow_id_out_buf_t ), - .id_t ( axi_narrow_out_id_t ) - ) i_narrow_aw_meta_buffer ( - .clk_i ( clk_i ), - .rst_ni ( rst_ni ), - .test_enable_i ( test_enable_i ), - .req_push_i ( narrow_aw_out_push ), - .req_valid_i ( axi_narrow_out_req_o.aw_valid ), - .req_buf_i ( narrow_aw_out_data_in ), - .req_is_atop_i ( is_atop ), - .req_atop_id_i ( '0 ), - .req_full_o ( narrow_aw_out_full ), - .req_id_o ( narrow_aw_out_id ), - .rsp_pop_i ( narrow_aw_out_pop ), - .rsp_id_i ( axi_narrow_out_rsp_i.b.id ), - .rsp_buf_o ( narrow_aw_out_data_out ) - ); - - - floo_meta_buffer #( - .MaxTxns ( NarrowMaxTxns ), - .AtopSupport ( AtopSupport ), - .MaxAtomicTxns ( MaxAtomicTxns ), - .ExtAtomicId ( 1'b1 ), // Use ID from AW channel - .buf_t ( narrow_id_out_buf_t ), - .id_t ( axi_narrow_out_id_t ) - ) i_narrow_ar_meta_buffer ( - .clk_i ( clk_i ), - .rst_ni ( rst_ni ), - .test_enable_i ( test_enable_i ), - .req_push_i ( narrow_ar_out_push ), - .req_valid_i ( axi_narrow_out_req_o.ar_valid ), - .req_buf_i ( narrow_ar_out_data_in ), - .req_is_atop_i ( is_atop ), - .req_atop_id_i ( narrow_aw_out_id ), // Use ID from AW channel - .req_full_o ( narrow_ar_out_full ), - .req_id_o ( narrow_ar_out_id ), - .rsp_pop_i ( narrow_ar_out_pop ), - .rsp_id_i ( axi_narrow_out_rsp_i.r.id ), - .rsp_buf_o ( narrow_ar_out_data_out ) - ); - - floo_meta_buffer #( - .MaxTxns ( NarrowMaxTxns ), - .AtopSupport ( 1'b0 ), - .buf_t ( wide_id_out_buf_t ), - .id_t ( axi_wide_out_id_t ) - ) i_wide_aw_meta_buffer ( - .clk_i ( clk_i ), - .rst_ni ( rst_ni ), - .test_enable_i ( test_enable_i ), - .req_push_i ( wide_aw_out_push ), - .req_valid_i ( axi_wide_out_req_o.aw_valid ), - .req_buf_i ( wide_aw_out_data_in ), - .req_is_atop_i ( 1'b0 ), - .req_atop_id_i ( '0 ), - .req_full_o ( wide_aw_out_full ), - .req_id_o ( wide_aw_out_id ), - .rsp_pop_i ( wide_aw_out_pop ), - .rsp_id_i ( axi_wide_out_rsp_i.b.id ), - .rsp_buf_o ( wide_aw_out_data_out ) + .IdInWidth ( NarrowInIdWidth ), + .IdOutWidth ( NarrowOutIdWidth ), + .axi_req_t ( axi_narrow_in_req_t ), + .axi_rsp_t ( axi_narrow_in_rsp_t ) + ) i_narrow_meta_buffer ( + .clk_i, + .rst_ni, + .test_enable_i, + .axi_req_i ( axi_narrow_meta_buf_req_in ), + .axi_rsp_o ( axi_narrow_meta_buf_rsp_out ), + .axi_req_o ( axi_narrow_meta_buf_req_out ), + .axi_rsp_i ( axi_narrow_meta_buf_rsp_in ), + .aw_buf_i ( narrow_aw_out_data_in ), + .ar_buf_i ( narrow_ar_out_data_in ), + .r_buf_o ( narrow_ar_out_data_out ), + .b_buf_o ( narrow_aw_out_data_out ) ); floo_meta_buffer #( - .MaxTxns ( NarrowMaxTxns ), - .AtopSupport ( 1'b0 ), + .MaxTxns ( WideMaxTxns ), + .AtopSupport ( 1'b1 ), + .MaxAtomicTxns ( MaxAtomicTxns ), .buf_t ( wide_id_out_buf_t ), - .id_t ( axi_wide_out_id_t ) - ) i_wide_ar_meta_buffer ( - .clk_i ( clk_i ), - .rst_ni ( rst_ni ), - .test_enable_i ( test_enable_i ), - .req_push_i ( wide_ar_out_push ), - .req_valid_i ( axi_wide_out_req_o.ar_valid ), - .req_buf_i ( wide_ar_out_data_in ), - .req_is_atop_i ( 1'b0 ), - .req_atop_id_i ( '0 ), - .req_full_o ( wide_ar_out_full ), - .req_id_o ( wide_ar_out_id ), - .rsp_pop_i ( wide_ar_out_pop ), - .rsp_id_i ( axi_wide_out_rsp_i.r.id ), - .rsp_buf_o ( wide_ar_out_data_out ) + .IdInWidth ( WideInIdWidth ), + .IdOutWidth ( WideOutIdWidth ), + .axi_req_t ( axi_wide_in_req_t ), + .axi_rsp_t ( axi_wide_in_rsp_t ) + ) i_wide_meta_buffer ( + .clk_i, + .rst_ni, + .test_enable_i, + .axi_req_i ( axi_wide_meta_buf_req_in ), + .axi_rsp_o ( axi_wide_meta_buf_rsp_out ), + .axi_req_o ( axi_wide_meta_buf_req_out ), + .axi_rsp_i ( axi_wide_meta_buf_rsp_in ), + .aw_buf_i ( wide_aw_out_data_in ), + .ar_buf_i ( wide_ar_out_data_in ), + .r_buf_o ( wide_ar_out_data_out ), + .b_buf_o ( wide_aw_out_data_out ) ); - always_comb begin - // Assign the outgoing AX an unique ID - axi_narrow_aw_id_mod = axi_narrow_unpack_aw; - axi_narrow_ar_id_mod = axi_narrow_unpack_ar; - axi_wide_aw_id_mod = axi_wide_unpack_aw; - axi_wide_ar_id_mod = axi_wide_unpack_ar; - axi_narrow_aw_id_mod.id = narrow_aw_out_id; - axi_narrow_ar_id_mod.id = narrow_ar_out_id; - axi_wide_aw_id_mod.id = wide_aw_out_id; - axi_wide_ar_id_mod.id = wide_ar_out_id; - end - // Registers `FF(b_rob_pending_q, narrow_b_rob_valid_out && !narrow_b_rob_ready_in && !is_atop_b_rsp, '0) `FF(r_rob_pending_q, narrow_r_rob_valid_out && !narrow_r_rob_ready_in && !is_atop_r_rsp, '0) diff --git a/src/floo_pkg.sv b/src/floo_pkg.sv index f8c2c604..f583d5df 100644 --- a/src/floo_pkg.sv +++ b/src/floo_pkg.sv @@ -55,4 +55,10 @@ package floo_pkg; RucheWest = 'd8 } ruche_direction_e; + typedef enum logic [1:0] { + NormalRoB, + SimpleRoB, + NoRoB + } rob_type_e; + endpackage diff --git a/src/floo_rob_wrapper.sv b/src/floo_rob_wrapper.sv new file mode 100644 index 00000000..9c941241 --- /dev/null +++ b/src/floo_rob_wrapper.sv @@ -0,0 +1,178 @@ +// Copyright 2023 ETH Zurich and University of Bologna. +// Solderpad Hardware License, Version 0.51, see LICENSE for details. +// SPDX-License-Identifier: SHL-0.51 +// +// Author: Tim Fischer + +/// A wrapper of all available reorder buffers +module floo_rob_wrapper + import floo_pkg::*; +#( + /// Type of reorder buffer to use + parameter rob_type_e RoBType = NormalRoB, + /// Maximum number of transactions in flight per ID which *require* reordering + parameter int unsigned MaxRoTxnsPerId = 32'd32, + /// If the response only consists of small metadata i.e. B channel + /// In this case no SRAM will be instantied and the response will be + /// metadata will be stored in normal FFs + parameter bit OnlyMetaData = 1'b0, + /// Size of the reorder buffer + parameter int unsigned ReorderBufferSize = 32'd64, + /// Data type of response to be reordered + parameter type ax_len_t = logic, + parameter type ax_id_t = logic, + parameter type rsp_chan_t = logic, + parameter type rsp_data_t = logic, + parameter type rsp_meta_t = logic, + parameter type rob_idx_t = logic, + parameter type dest_t = logic, + // Type for implementation inputs and outputs + parameter type sram_cfg_t = logic +) ( + input logic clk_i, + input logic rst_ni, + input sram_cfg_t sram_cfg_i, + input logic ax_valid_i, + output logic ax_ready_o, + input ax_len_t ax_len_i, + input ax_id_t ax_id_i, + input dest_t ax_dest_i, + output logic ax_valid_o, + input logic ax_ready_i, + output logic ax_rob_req_o, + output rob_idx_t ax_rob_idx_o, + input logic rsp_valid_i, + output logic rsp_ready_o, + input rsp_chan_t rsp_i, + input logic rsp_rob_req_i, + input rob_idx_t rsp_rob_idx_i, + input logic rsp_last_i, + output logic rsp_valid_o, + input logic rsp_ready_i, + output rsp_chan_t rsp_o +); + + if (RoBType == NormalRoB) begin : gen_normal_rob + floo_rob #( + .ReorderBufferSize ( ReorderBufferSize ), + .MaxRoTxnsPerId ( MaxRoTxnsPerId ), + .OnlyMetaData ( OnlyMetaData ), + .ax_len_t ( ax_len_t ), + .ax_id_t ( ax_id_t ), + .rsp_chan_t ( rsp_chan_t ), + .rsp_data_t ( rsp_data_t ), + .rsp_meta_t ( rsp_meta_t ), + .rob_idx_t ( rob_idx_t ), + .dest_t ( dest_t ), + .sram_cfg_t ( sram_cfg_t ) + ) i_rob ( + .clk_i, + .rst_ni, + .sram_cfg_i, + .ax_valid_i, + .ax_ready_o, + .ax_len_i, + .ax_id_i, + .ax_dest_i, + .ax_valid_o, + .ax_ready_i, + .ax_rob_req_o, + .ax_rob_idx_o, + .rsp_valid_i, + .rsp_ready_o, + .rsp_i, + .rsp_rob_req_i, + .rsp_rob_idx_i, + .rsp_last_i, + .rsp_valid_o, + .rsp_ready_i, + .rsp_o + ); + + end else if (RoBType == SimpleRoB) begin : gen_simpl_rob + floo_simple_rob #( + .ReorderBufferSize ( ReorderBufferSize ), + .MaxRoTxnsPerId ( MaxRoTxnsPerId ), + .OnlyMetaData ( OnlyMetaData ), + .ax_len_t ( ax_len_t ), + .rsp_chan_t ( rsp_chan_t ), + .rsp_data_t ( rsp_data_t ), + .rsp_meta_t ( rsp_meta_t ), + .rob_idx_t ( rob_idx_t ), + .dest_t ( dest_t ), + .sram_cfg_t ( sram_cfg_t ) + ) i_rob ( + .clk_i, + .rst_ni, + .sram_cfg_i, + .ax_valid_i, + .ax_ready_o, + .ax_len_i, + .ax_dest_i, + .ax_valid_o, + .ax_ready_i, + .ax_rob_req_o, + .ax_rob_idx_o, + .rsp_valid_i, + .rsp_ready_o, + .rsp_i, + .rsp_rob_req_i, + .rsp_rob_idx_i, + .rsp_last_i, + .rsp_valid_o, + .rsp_ready_i, + .rsp_o + ); + + end else if (RoBType == NoRoB) begin : gen_no_rob + + localparam int unsigned AxiIdBits = $bits(ax_id_i); + localparam int unsigned CounterWidth = $clog2(MaxRoTxnsPerId); + + logic push, pop; + logic in_flight; + dest_t prev_dest; + + // A new transaction can be pushed if it is the first one + // i.e. `in_flight` is not set or if the previous transaction + // has the same destination + assign push = ax_valid_i && (!in_flight || ax_dest_i == prev_dest); + // Whenever a response arrives we can pop the transaction + assign pop = rsp_valid_i && rsp_last_i; + + assign ax_valid_o = push; + assign ax_ready_o = push && ax_ready_i; + + assign ax_rob_req_o = 1'b1; + assign ax_rob_idx_o = '0; + + assign rsp_ready_o = rsp_ready_i; + assign rsp_valid_o = rsp_valid_i; + assign rsp_o = rsp_i; + + + axi_demux_id_counters #( + .AxiIdBits ( AxiIdBits ), + .CounterWidth ( CounterWidth ), + .mst_port_select_t ( dest_t ) + ) i_axi_demux_id_counters ( + .clk_i, + .rst_ni, + .lookup_axi_id_i ( ax_id_i ), + .lookup_mst_select_o ( prev_dest ), + .lookup_mst_select_occupied_o ( in_flight ), + .full_o ( /* TODO */ ), + .push_axi_id_i ( ax_id_i ), + .push_mst_select_i ( ax_dest_i ), + .push_i ( push && ax_ready_i ), // Only push on handshake + .inject_axi_id_i ( '0 ), + .inject_i ( 1'b0 ), + .pop_axi_id_i ( rsp_i.id ), + .pop_i ( pop && rsp_ready_i ) // Only pop on handshake + ); + + end else begin : gen_error + $error("Unknown RoB type %0d", RoBType); + end + +endmodule diff --git a/src/synth/floo_synth_narrow_wide_chimney.sv b/src/synth/floo_synth_narrow_wide_chimney.sv index 52a0e230..90444c6f 100644 --- a/src/synth/floo_synth_narrow_wide_chimney.sv +++ b/src/synth/floo_synth_narrow_wide_chimney.sv @@ -46,10 +46,10 @@ floo_narrow_wide_chimney #( .WideMaxTxns ( WideMaxTxnsPerId ), .NarrowMaxTxnsPerId ( NarrowMaxTxnsPerId ), .WideMaxTxnsPerId ( WideMaxTxnsPerId ), + .NarrowRoBType ( NarrowRoBType ), + .WideRoBType ( WideRoBType ), .NarrowReorderBufferSize ( NarrowReorderBufferSize ), .WideReorderBufferSize ( WideReorderBufferSize ), - .NarrowRoBSimple ( NarrowRoBSimple ), - .WideRoBSimple ( WideRoBSimple ), .CutAx ( CutAx ), .CutRsp ( CutRsp ), .xy_id_t ( xy_id_t ), diff --git a/test/floo_test_pkg.sv b/test/floo_test_pkg.sv index cae694ce..bb3a7e1e 100644 --- a/test/floo_test_pkg.sv +++ b/test/floo_test_pkg.sv @@ -8,6 +8,8 @@ package floo_test_pkg; + import floo_pkg::*; + typedef enum { FastSlave, SlowSlave, @@ -27,15 +29,16 @@ package floo_test_pkg; localparam bit CutAx = 1'b1; localparam bit CutRsp = 1'b0; localparam int unsigned MaxTxnsPerId = 16; - localparam bit RoBSimple = 1'b0; + localparam rob_type_e RoBType = NormalRoB; localparam int unsigned ReorderBufferSize = 32'd64; // Narrow Wide Chimney parameters localparam bit NarrowRoBSimple = 1'b1; localparam int unsigned NarrowMaxTxnsPerId = 4; + localparam rob_type_e NarrowRoBType = NoRoB; localparam int unsigned NarrowReorderBufferSize = 32'd256; - localparam bit WideRoBSimple = 1'b0; localparam int unsigned WideMaxTxnsPerId = 32; + localparam rob_type_e WideRoBType = NoRoB; localparam int unsigned WideReorderBufferSize = 32'd128; `FLOO_NOC_TYPEDEF_XY_ID_T(xy_id_t, NumX, NumY) diff --git a/test/tb_floo_axi_chimney.sv b/test/tb_floo_axi_chimney.sv index a9d85932..21a03edd 100644 --- a/test/tb_floo_axi_chimney.sv +++ b/test/tb_floo_axi_chimney.sv @@ -22,6 +22,8 @@ module tb_floo_axi_chimney; localparam NumReads1 = 1000; localparam NumWrites1 = 1000; + localparam bit AtopSupport = 1'b1; + localparam NumTargets = 2; localparam int unsigned ReorderBufferSize = 64; @@ -79,7 +81,7 @@ module tb_floo_axi_chimney; .slv_rsp_t ( axi_out_rsp_t ), .ApplTime ( ApplTime ), .TestTime ( TestTime ), - .Atops ( 1'b1 ), + .Atops ( AtopSupport ), .AxiMaxBurstLen ( ReorderBufferSize ), .NumAddrRegions ( NumAddrRegions ), .rule_t ( node_addr_region_t ), @@ -116,7 +118,7 @@ module tb_floo_axi_chimney; ); floo_axi_chimney #( - .AtopSupport ( 1'b1 ), + .AtopSupport ( AtopSupport ), .MaxAtomicTxns ( 4 ), .RouteAlgo ( floo_pkg::IdTable ), .MaxTxns ( MaxTxns ), @@ -140,7 +142,7 @@ module tb_floo_axi_chimney; ); floo_axi_chimney #( - .AtopSupport ( 1'b1 ), + .AtopSupport ( AtopSupport ), .MaxAtomicTxns ( 4 ), .RouteAlgo ( floo_pkg::IdTable ), .MaxTxns ( MaxTxns ), @@ -189,12 +191,12 @@ module tb_floo_axi_chimney; .AxiIdOutWidth ( AxiInIdWidth ), .AxiUserWidth ( AxiInUserWidth ), .mst_req_t ( axi_in_req_t ), - .mst_rsp_t ( axi_in_rsp_t ), + .mst_rsp_t ( axi_in_rsp_t ), .slv_req_t ( axi_out_req_t ), - .slv_rsp_t ( axi_out_rsp_t ), + .slv_rsp_t ( axi_out_rsp_t ), .ApplTime ( ApplTime ), .TestTime ( TestTime ), - .Atops ( 1'b1 ), + .Atops ( AtopSupport ), .AxiMaxBurstLen ( ReorderBufferSize ), .NumAddrRegions ( NumAddrRegions ), .rule_t ( node_addr_region_t ), diff --git a/test/tb_floo_axi_chimney.wave.tcl b/test/tb_floo_axi_chimney.wave.tcl index bf071cbe..89b19b90 100644 --- a/test/tb_floo_axi_chimney.wave.tcl +++ b/test/tb_floo_axi_chimney.wave.tcl @@ -8,6 +8,7 @@ quietly WaveActivateNextPane {} 0 delete wave * set num_phys_channels [expr [llength [find instances -bydu floo_wormhole_arbiter]] / 2 / 2] +set normal_rob [expr [llength [find instances -bydu floo_rob]] / 2 == 2] set simple_rob [expr [llength [find instances -bydu floo_simple_rob]] / 2 == 2] for {set i 0} {$i < 2} {incr i} { @@ -33,14 +34,18 @@ for {set i 0} {$i < 2} {incr i} { add wave -noupdate -expand -group $group_name -group Unpacker tb_floo_axi_chimney/i_floo_axi_chimney_${i}/axi_unpack_b add wave -noupdate -expand -group $group_name -group Unpacker tb_floo_axi_chimney/i_floo_axi_chimney_${i}/axi_unpack_r - add wave -noupdate -expand -group $group_name -group AwMetaBuffer tb_floo_axi_chimney/i_floo_axi_chimney_${i}/i_aw_meta_buffer/* - add wave -noupdate -expand -group $group_name -group ArMetaBuffer tb_floo_axi_chimney/i_floo_axi_chimney_${i}/i_ar_meta_buffer/* + add wave -noupdate -expand -group $group_name -group MetaBuffer tb_floo_axi_chimney/i_floo_axi_chimney_${i}/i_floo_meta_buffer/* + try { + add wave -noupdate -expand -group $group_name -group MetaBuffer tb_floo_axi_chimney/i_floo_axi_chimney_${i}/i_floo_meta_buffer/gen_atop_support/* + } - if {!$simple_rob} { + if {$normal_rob} { add wave -noupdate -expand -group $group_name -group R_RoB -group StatusTable tb_floo_axi_chimney/i_floo_axi_chimney_${i}/gen_rob/i_r_rob/i_floo_rob_status_table/* add wave -noupdate -expand -group $group_name -group R_RoB tb_floo_axi_chimney/i_floo_axi_chimney_${i}/gen_rob/i_r_rob/* - } else { + } elseif {$simple_rob} { add wave -noupdate -expand -group $group_name -group R_RoB tb_floo_axi_chimney/i_floo_axi_chimney_${i}/gen_simple_rob/i_r_rob/* + } else { + add wave -noupdate -expand -group $group_name -group R_RoB tb_floo_axi_chimney/i_floo_axi_chimney_${i}/i_r_rob/* } add wave -noupdate -expand -group $group_name -group B_RoB tb_floo_axi_chimney/i_floo_axi_chimney_${i}/i_b_rob/* diff --git a/test/tb_floo_narrow_wide_chimney.sv b/test/tb_floo_narrow_wide_chimney.sv index 6c4320fd..ca655a43 100644 --- a/test/tb_floo_narrow_wide_chimney.sv +++ b/test/tb_floo_narrow_wide_chimney.sv @@ -17,10 +17,12 @@ module tb_floo_narrow_wide_chimney; localparam time ApplTime = 2ns; localparam time TestTime = 8ns; - localparam NarrowNumReads = 100; - localparam NarrowNumWrites = 100; - localparam WideNumReads = 100; - localparam WideNumWrites = 100; + localparam NarrowNumReads = 1000; + localparam NarrowNumWrites = 1000; + localparam WideNumReads = 1000; + localparam WideNumWrites = 1000; + + localparam bit AtopSupport = 1'b1; localparam NumTargets = 2; @@ -100,7 +102,7 @@ module tb_floo_narrow_wide_chimney; .slv_rsp_t ( axi_narrow_out_rsp_t ), .ApplTime ( ApplTime ), .TestTime ( TestTime ), - .Atops ( 1'b1 ), + .Atops ( AtopSupport ), .AxiMaxBurstLen ( ReorderBufferSize ), .NumAddrRegions ( NumAddrRegions ), .rule_t ( node_addr_region_t ), @@ -182,7 +184,7 @@ module tb_floo_narrow_wide_chimney; ); floo_narrow_wide_chimney #( - .AtopSupport ( 1'b1 ), + .AtopSupport ( AtopSupport ), .MaxAtomicTxns ( 1 ), .RouteAlgo ( floo_pkg::IdTable ), .NumIDs ( NumTargets ), @@ -193,7 +195,9 @@ module tb_floo_narrow_wide_chimney; .NarrowReorderBufferSize ( ReorderBufferSize ), .WideMaxTxns ( MaxTxns ), .WideMaxTxnsPerId ( MaxTxnsPerId ), - .WideReorderBufferSize ( ReorderBufferSize ) + .WideReorderBufferSize ( ReorderBufferSize ), + .CutAx ( 1'b0 ), + .CutRsp ( 1'b0 ) ) i_floo_narrow_wide_chimney_0 ( .clk_i ( clk ), .rst_ni ( rst_n ), @@ -219,7 +223,7 @@ module tb_floo_narrow_wide_chimney; ); floo_narrow_wide_chimney #( - .AtopSupport ( 1'b1 ), + .AtopSupport ( AtopSupport ), .MaxAtomicTxns ( 1 ), .RouteAlgo ( floo_pkg::IdTable ), .NumIDs ( NumTargets ), @@ -230,7 +234,9 @@ module tb_floo_narrow_wide_chimney; .NarrowReorderBufferSize ( ReorderBufferSize ), .WideMaxTxns ( MaxTxns ), .WideMaxTxnsPerId ( MaxTxnsPerId ), - .WideReorderBufferSize ( ReorderBufferSize ) + .WideReorderBufferSize ( ReorderBufferSize ), + .CutAx ( 1'b0 ), + .CutRsp ( 1'b0 ) ) i_floo_narrow_wide_chimney_1 ( .clk_i ( clk ), .rst_ni ( rst_n ), @@ -302,7 +308,7 @@ module tb_floo_narrow_wide_chimney; .slv_rsp_t ( axi_narrow_out_rsp_t ), .ApplTime ( ApplTime ), .TestTime ( TestTime ), - .Atops ( 1'b1 ), + .Atops ( AtopSupport ), .AxiMaxBurstLen ( ReorderBufferSize ), .NumAddrRegions ( NumAddrRegions ), .rule_t ( node_addr_region_t ), diff --git a/test/tb_floo_narrow_wide_chimney.wave.tcl b/test/tb_floo_narrow_wide_chimney.wave.tcl index 59d52b21..ab71a439 100644 --- a/test/tb_floo_narrow_wide_chimney.wave.tcl +++ b/test/tb_floo_narrow_wide_chimney.wave.tcl @@ -8,6 +8,7 @@ quietly WaveActivateNextPane {} 0 delete wave * set num_phys_channels [expr [llength [find instances -bydu floo_wormhole_arbiter]] / 2 / 2] +set normal_rob [expr [llength [find instances -bydu floo_rob]] / 2 == 4] set simple_rob [expr [llength [find instances -bydu floo_simple_rob]] / 2 == 4] for {set i 0} {$i < 2} {incr i} { @@ -30,6 +31,8 @@ for {set i 0} {$i < 2} {incr i} { add wave -noupdate -expand -group $group_name -group Packer tb_floo_narrow_wide_chimney/i_floo_narrow_wide_chimney_${i}/floo_wide_ar add wave -noupdate -expand -group $group_name -group Packer tb_floo_narrow_wide_chimney/i_floo_narrow_wide_chimney_${i}/floo_wide_r + add wave -noupdate -expand -group $group_name -group Unpacker tb_floo_narrow_wide_chimney/i_floo_narrow_wide_chimney_${i}/axi_valid_in + add wave -noupdate -expand -group $group_name -group Unpacker tb_floo_narrow_wide_chimney/i_floo_narrow_wide_chimney_${i}/axi_ready_out add wave -noupdate -expand -group $group_name -group Unpacker tb_floo_narrow_wide_chimney/i_floo_narrow_wide_chimney_${i}/axi_narrow_unpack_aw add wave -noupdate -expand -group $group_name -group Unpacker tb_floo_narrow_wide_chimney/i_floo_narrow_wide_chimney_${i}/axi_narrow_unpack_w add wave -noupdate -expand -group $group_name -group Unpacker tb_floo_narrow_wide_chimney/i_floo_narrow_wide_chimney_${i}/axi_narrow_unpack_ar @@ -41,19 +44,31 @@ for {set i 0} {$i < 2} {incr i} { add wave -noupdate -expand -group $group_name -group Unpacker tb_floo_narrow_wide_chimney/i_floo_narrow_wide_chimney_${i}/axi_wide_unpack_b add wave -noupdate -expand -group $group_name -group Unpacker tb_floo_narrow_wide_chimney/i_floo_narrow_wide_chimney_${i}/axi_wide_unpack_r - if {!$simple_rob} { + if {$normal_rob} { add wave -noupdate -expand -group $group_name -group NarrowR_RoB -group StatusTable tb_floo_narrow_wide_chimney/i_floo_narrow_wide_chimney_${i}/gen_narrow_rob/i_narrow_r_rob/i_floo_rob_status_table/* add wave -noupdate -expand -group $group_name -group NarrowR_RoB tb_floo_narrow_wide_chimney/i_floo_narrow_wide_chimney_${i}/gen_narrow_rob/i_narrow_r_rob/* add wave -noupdate -expand -group $group_name -group WideR_RoB -group StatusTable tb_floo_narrow_wide_chimney/i_floo_narrow_wide_chimney_${i}/gen_wide_rob/i_wide_r_rob/i_floo_rob_status_table/* add wave -noupdate -expand -group $group_name -group WideR_RoB tb_floo_narrow_wide_chimney/i_floo_narrow_wide_chimney_${i}/gen_wide_rob/i_wide_r_rob/* - } else { + } elseif {$simple_rob} { add wave -noupdate -expand -group $group_name -group NarrowR_RoB tb_floo_narrow_wide_chimney/i_floo_narrow_wide_chimney_${i}/gen_simple_rob/i_narrow_r_rob/* add wave -noupdate -expand -group $group_name -group WideR_RoB tb_floo_narrow_wide_chimney/i_floo_narrow_wide_chimney_${i}/gen_simple_rob/i_wide_r_rob/* + } else { + add wave -noupdate -expand -group $group_name -group NarrowR_RoB tb_floo_narrow_wide_chimney/i_floo_narrow_wide_chimney_${i}/i_narrow_r_rob/* + add wave -noupdate -expand -group $group_name -group WideR_RoB tb_floo_narrow_wide_chimney/i_floo_narrow_wide_chimney_${i}/i_wide_r_rob/* } add wave -noupdate -expand -group $group_name -group NarrowB_RoB tb_floo_narrow_wide_chimney/i_floo_narrow_wide_chimney_${i}/i_narrow_b_rob/* add wave -noupdate -expand -group $group_name -group WideB_RoB tb_floo_narrow_wide_chimney/i_floo_narrow_wide_chimney_${i}/i_wide_b_rob/* + add wave -noupdate -expand -group $group_name -group NarrowMetaBuffer tb_floo_narrow_wide_chimney/i_floo_narrow_wide_chimney_${i}/i_narrow_meta_buffer/* + try { + add wave -noupdate -expand -group $group_name -group NarrowMetaBuffer tb_floo_narrow_wide_chimney/i_floo_narrow_wide_chimney_${i}/i_narrow_meta_buffer/gen_atop_support/* + } + add wave -noupdate -expand -group $group_name -group WideMetaBuffer tb_floo_narrow_wide_chimney/i_floo_narrow_wide_chimney_${i}/i_wide_meta_buffer/* + try { + add wave -noupdate -expand -group $group_name -group WideMetaBuffer tb_floo_narrow_wide_chimney/i_floo_narrow_wide_chimney_${i}/i_wide_meta_buffer/gen_atop_support/* + } + } TreeUpdate [SetDefaultTree]