From cf4aa87aa4a53c780861b60cfd7d9c6a13e2cfae Mon Sep 17 00:00:00 2001 From: Tim Fischer Date: Tue, 26 Sep 2023 16:34:29 +0200 Subject: [PATCH 01/13] rob: Add wrapper to select between different RoB + support NoRoB --- Bender.yml | 1 + src/floo_axi_chimney.sv | 112 +++++++------------ src/floo_pkg.sv | 6 + src/floo_rob_wrapper.sv | 178 ++++++++++++++++++++++++++++++ test/tb_floo_axi_chimney.wave.tcl | 7 +- 5 files changed, 231 insertions(+), 73 deletions(-) create mode 100644 src/floo_rob_wrapper.sv 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/src/floo_axi_chimney.sv b/src/floo_axi_chimney.sv index a694ad8a..689f1e45 100644 --- a/src/floo_axi_chimney.sv +++ b/src/floo_axi_chimney.sv @@ -244,11 +244,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 +263,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 +288,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 // 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..f529fe73 --- /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 + $error("Unknown RoB type %0d", RoBType); + end + +endmodule diff --git a/test/tb_floo_axi_chimney.wave.tcl b/test/tb_floo_axi_chimney.wave.tcl index bf071cbe..a193e9b3 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} { @@ -36,11 +37,13 @@ for {set i 0} {$i < 2} {incr i} { 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/* - 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/* From b4e2e998ec0b58c6cd67b343b967272266c1a7d2 Mon Sep 17 00:00:00 2001 From: Tim Fischer Date: Tue, 26 Sep 2023 16:35:23 +0200 Subject: [PATCH 02/13] test: `AtopSupport` as dedicated parameter --- test/tb_floo_axi_chimney.sv | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) 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 ), From faf443f4950be1e9f2e4bef98b2121ab88b53d41 Mon Sep 17 00:00:00 2001 From: Tim Fischer Date: Wed, 27 Sep 2023 13:57:02 +0200 Subject: [PATCH 03/13] nw_chimney: Don't use a reorder buffer --- src/floo_narrow_wide_chimney.sv | 240 +++++++------------- src/synth/floo_synth_narrow_wide_chimney.sv | 4 +- test/floo_test_pkg.sv | 7 +- 3 files changed, 94 insertions(+), 157 deletions(-) diff --git a/src/floo_narrow_wide_chimney.sv b/src/floo_narrow_wide_chimney.sv index 600c75f2..67395105 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 @@ -377,14 +375,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 +394,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 +418,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 +437,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 +475,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 +519,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 // 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) From 65876a4a775bb700665278cb484e3859c520b148 Mon Sep 17 00:00:00 2001 From: Tim Fischer Date: Wed, 27 Sep 2023 15:54:36 +0200 Subject: [PATCH 04/13] chimney: Fix atop bug --- src/floo_axi_chimney.sv | 10 +++++++--- src/floo_meta_buffer.sv | 21 ++++++++++++++++----- src/floo_narrow_wide_chimney.sv | 13 ++++++++++++- 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/src/floo_axi_chimney.sv b/src/floo_axi_chimney.sv index 689f1e45..e0f387ea 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 @@ -124,6 +121,9 @@ module floo_axi_chimney logic atop; } id_out_buf_t; + typedef logic [MaxAtomicTxns-1:0] atop_id_mask_t; + atop_id_mask_t atop_id_mask_ar, atop_id_mask_aw; + // Routing id_t [NumAxiChannels-1:0] dst_id; id_t src_id; @@ -585,6 +585,8 @@ module floo_axi_chimney .req_buf_i ( aw_out_data_in ), .req_is_atop_i ( is_atop ), .req_atop_id_i ( '0 ), + .avl_atop_ids_i ( atop_id_mask_ar ), + .avl_atop_ids_o ( atop_id_mask_aw ), .req_full_o ( aw_out_full ), .req_id_o ( aw_out_id ), .rsp_pop_i ( aw_out_pop ), @@ -608,6 +610,8 @@ module floo_axi_chimney .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 + .avl_atop_ids_i ( atop_id_mask_aw ), + .avl_atop_ids_o ( atop_id_mask_ar ), .req_full_o ( ar_out_full ), .req_id_o ( ar_out_id ), .rsp_pop_i ( ar_out_pop ), diff --git a/src/floo_meta_buffer.sv b/src/floo_meta_buffer.sv index dc0a782a..41b97a63 100644 --- a/src/floo_meta_buffer.sv +++ b/src/floo_meta_buffer.sv @@ -21,10 +21,14 @@ module floo_meta_buffer #( parameter bit ExtAtomicId = 1'b0, /// Information to be buffered for responses parameter type buf_t = logic, + /// ID width + parameter int IdWidth = 32'd1, /// ID type for outgoing requests - parameter type id_t = logic, + parameter type id_t = logic [IdWidth-1:0], /// Constant ID for non-atomic requests - localparam id_t NonAtomicId = '1 + localparam id_t NonAtomicId = '1, + /// mask of available Atomic IDs + localparam type id_mask_t = logic [MaxAtomicTxns-1:0] ) ( input logic clk_i, input logic rst_ni, @@ -34,6 +38,8 @@ module floo_meta_buffer #( input buf_t req_buf_i, input logic req_is_atop_i, input id_t req_atop_id_i, + input id_mask_t avl_atop_ids_i, + output id_mask_t avl_atop_ids_o, output logic req_full_o, output id_t req_id_o, input logic rsp_pop_i, @@ -91,6 +97,10 @@ module floo_meta_buffer #( .data_o ( atop_data_out ) ); + assign avl_atop_ids_o = ~atop_req_out_full; + + `ASSERT(PushingToPendingAtomicTxns, (atop_req_out_push & atop_req_out_full) == '0) + 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. @@ -103,9 +113,9 @@ module floo_meta_buffer #( lzc #( .WIDTH (MaxAtomicTxns) ) i_lzc ( - .in_i ( next_free_slots ), - .cnt_o ( lzc_cnt ), - .empty_o ( ) + .in_i ( next_free_slots & avl_atop_ids_i ), + .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; @@ -128,6 +138,7 @@ module floo_meta_buffer #( assign req_id_o = NonAtomicId; assign rsp_buf_o = no_atop_buf_out; assign req_full_o = no_atop_buf_full; + assign avl_atop_ids_o = '0; end `ASSERT(NoAtopSupport, !(!AtopSupport && (req_push_i && req_is_atop_i))) diff --git a/src/floo_narrow_wide_chimney.sv b/src/floo_narrow_wide_chimney.sv index 67395105..c4577ded 100644 --- a/src/floo_narrow_wide_chimney.sv +++ b/src/floo_narrow_wide_chimney.sv @@ -178,6 +178,9 @@ module floo_narrow_wide_chimney id_t src_id; } wide_id_out_buf_t; + typedef logic [MaxAtomicTxns-1:0] atop_id_mask_t; + atop_id_mask_t atop_id_mask_ar, atop_id_mask_aw; + // Routing id_t [NumNarrowWideAxiChannels-1:0] dst_id; id_t src_id; @@ -1036,12 +1039,14 @@ module floo_narrow_wide_chimney .req_buf_i ( narrow_aw_out_data_in ), .req_is_atop_i ( is_atop ), .req_atop_id_i ( '0 ), + .avl_atop_ids_i ( atop_id_mask_ar ), + .avl_atop_ids_o ( atop_id_mask_aw ), .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 #( @@ -1060,6 +1065,8 @@ module floo_narrow_wide_chimney .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 + .avl_atop_ids_i ( atop_id_mask_aw ), + .avl_atop_ids_o ( atop_id_mask_ar ), .req_full_o ( narrow_ar_out_full ), .req_id_o ( narrow_ar_out_id ), .rsp_pop_i ( narrow_ar_out_pop ), @@ -1081,6 +1088,8 @@ module floo_narrow_wide_chimney .req_buf_i ( wide_aw_out_data_in ), .req_is_atop_i ( 1'b0 ), .req_atop_id_i ( '0 ), + .avl_atop_ids_i ( '0 ), + .avl_atop_ids_o ( ), .req_full_o ( wide_aw_out_full ), .req_id_o ( wide_aw_out_id ), .rsp_pop_i ( wide_aw_out_pop ), @@ -1102,6 +1111,8 @@ module floo_narrow_wide_chimney .req_buf_i ( wide_ar_out_data_in ), .req_is_atop_i ( 1'b0 ), .req_atop_id_i ( '0 ), + .avl_atop_ids_i ( '0 ), + .avl_atop_ids_o ( ), .req_full_o ( wide_ar_out_full ), .req_id_o ( wide_ar_out_id ), .rsp_pop_i ( wide_ar_out_pop ), From 440ce9b2b7d5d04c11f1214e6f99df13dc5a9772 Mon Sep 17 00:00:00 2001 From: Tim Fischer Date: Wed, 27 Sep 2023 16:02:18 +0200 Subject: [PATCH 05/13] lint: System Verilog sources --- src/floo_rob_wrapper.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/floo_rob_wrapper.sv b/src/floo_rob_wrapper.sv index f529fe73..9c941241 100644 --- a/src/floo_rob_wrapper.sv +++ b/src/floo_rob_wrapper.sv @@ -171,7 +171,7 @@ module floo_rob_wrapper .pop_i ( pop && rsp_ready_i ) // Only pop on handshake ); - end else begin + end else begin : gen_error $error("Unknown RoB type %0d", RoBType); end From a10b1f6b1f42a8a192ebc9ed68e72a422d1a9acf Mon Sep 17 00:00:00 2001 From: Tim Fischer Date: Wed, 4 Oct 2023 11:17:05 +0200 Subject: [PATCH 06/13] meta_buffer: Merge read and write modules --- src/floo_meta_buffer.sv | 235 +++++++++++++++++++++++++--------------- 1 file changed, 146 insertions(+), 89 deletions(-) diff --git a/src/floo_meta_buffer.sv b/src/floo_meta_buffer.sv index 41b97a63..364a7fc2 100644 --- a/src/floo_meta_buffer.sv +++ b/src/floo_meta_buffer.sv @@ -17,130 +17,187 @@ 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 width - parameter int IdWidth = 32'd1, - /// ID type for outgoing requests - parameter type id_t = logic [IdWidth-1:0], + /// 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, - /// mask of available Atomic IDs - localparam type id_mask_t = logic [MaxAtomicTxns-1:0] + 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, - input id_mask_t avl_atop_ids_i, - output id_mask_t avl_atop_ids_o, - 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 ) ); - assign avl_atop_ids_o = ~atop_req_out_full; - - `ASSERT(PushingToPendingAtomicTxns, (atop_req_out_push & atop_req_out_full) == '0) - - 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 & avl_atop_ids_i ), - .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; - assign avl_atop_ids_o = '0; + 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 From 2ce0942e4515d57ef17b66fab0d3d48ebcdd494c Mon Sep 17 00:00:00 2001 From: Tim Fischer Date: Wed, 4 Oct 2023 11:17:38 +0200 Subject: [PATCH 07/13] chimneys: Integrate new meta buffer --- src/floo_axi_chimney.sv | 136 +++++-------- src/floo_narrow_wide_chimney.sv | 335 ++++++++++++-------------------- 2 files changed, 165 insertions(+), 306 deletions(-) diff --git a/src/floo_axi_chimney.sv b/src/floo_axi_chimney.sv index e0f387ea..8f2cb71b 100644 --- a/src/floo_axi_chimney.sv +++ b/src/floo_axi_chimney.sv @@ -71,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; @@ -89,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; @@ -106,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; @@ -121,19 +120,10 @@ module floo_axi_chimney logic atop; } id_out_buf_t; - typedef logic [MaxAtomicTxns-1:0] atop_id_mask_t; - atop_id_mask_t atop_id_mask_ar, atop_id_mask_aw; - // Routing 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; @@ -407,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 @@ -420,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 @@ -437,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; @@ -511,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; @@ -524,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; @@ -534,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; @@ -548,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, @@ -575,58 +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 ), - .avl_atop_ids_i ( atop_id_mask_ar ), - .avl_atop_ids_o ( atop_id_mask_aw ), - .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 - .avl_atop_ids_i ( atop_id_mask_aw ), - .avl_atop_ids_o ( atop_id_mask_ar ), - .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_narrow_wide_chimney.sv b/src/floo_narrow_wide_chimney.sv index c4577ded..84fbd75b 100644 --- a/src/floo_narrow_wide_chimney.sv +++ b/src/floo_narrow_wide_chimney.sv @@ -56,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; @@ -132,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; @@ -162,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; @@ -178,27 +171,12 @@ module floo_narrow_wide_chimney id_t src_id; } wide_id_out_buf_t; - typedef logic [MaxAtomicTxns-1:0] atop_id_mask_t; - atop_id_mask_t atop_id_mask_ar, atop_id_mask_aw; - // Routing 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; @@ -684,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 @@ -697,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 @@ -742,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 @@ -754,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 @@ -789,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; @@ -919,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; @@ -959,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; @@ -982,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, @@ -1005,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, @@ -1029,109 +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 ), - .avl_atop_ids_i ( atop_id_mask_ar ), - .avl_atop_ids_o ( atop_id_mask_aw ), - .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 - .avl_atop_ids_i ( atop_id_mask_aw ), - .avl_atop_ids_o ( atop_id_mask_ar ), - .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 ), - .avl_atop_ids_i ( '0 ), - .avl_atop_ids_o ( ), - .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 ), - .avl_atop_ids_i ( '0 ), - .avl_atop_ids_o ( ), - .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) From 4676868199d06f6a518c7a0a5fc6deeafe4f16eb Mon Sep 17 00:00:00 2001 From: Tim Fischer Date: Wed, 4 Oct 2023 11:18:07 +0200 Subject: [PATCH 08/13] test: Increase test size again to 1000 transactions --- test/tb_floo_narrow_wide_chimney.sv | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/tb_floo_narrow_wide_chimney.sv b/test/tb_floo_narrow_wide_chimney.sv index 6c4320fd..6e825645 100644 --- a/test/tb_floo_narrow_wide_chimney.sv +++ b/test/tb_floo_narrow_wide_chimney.sv @@ -17,10 +17,10 @@ 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 NumTargets = 2; From 834549150ec2039513fec4396b8e43f9d14f6b41 Mon Sep 17 00:00:00 2001 From: Tim Fischer Date: Wed, 4 Oct 2023 11:18:39 +0200 Subject: [PATCH 09/13] test: Add `AtopSupport` parameter to testbench --- test/tb_floo_narrow_wide_chimney.sv | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/test/tb_floo_narrow_wide_chimney.sv b/test/tb_floo_narrow_wide_chimney.sv index 6e825645..ea520bbb 100644 --- a/test/tb_floo_narrow_wide_chimney.sv +++ b/test/tb_floo_narrow_wide_chimney.sv @@ -22,6 +22,8 @@ module tb_floo_narrow_wide_chimney; localparam WideNumReads = 1000; localparam WideNumWrites = 1000; + localparam bit AtopSupport = 1'b1; + localparam NumTargets = 2; localparam int unsigned ReorderBufferSize = 128; @@ -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 ), @@ -219,7 +221,7 @@ module tb_floo_narrow_wide_chimney; ); floo_narrow_wide_chimney #( - .AtopSupport ( 1'b1 ), + .AtopSupport ( AtopSupport ), .MaxAtomicTxns ( 1 ), .RouteAlgo ( floo_pkg::IdTable ), .NumIDs ( NumTargets ), @@ -302,7 +304,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 ), From 59f683fb555b6f295814b2873d505fcc2019de50 Mon Sep 17 00:00:00 2001 From: Tim Fischer Date: Wed, 4 Oct 2023 11:19:08 +0200 Subject: [PATCH 10/13] test: Don't cut the inputs for easier debugging --- test/tb_floo_narrow_wide_chimney.sv | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/test/tb_floo_narrow_wide_chimney.sv b/test/tb_floo_narrow_wide_chimney.sv index ea520bbb..ca655a43 100644 --- a/test/tb_floo_narrow_wide_chimney.sv +++ b/test/tb_floo_narrow_wide_chimney.sv @@ -195,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 ), @@ -232,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 ), From 8d590a65dff6f9e445dcb0fcdcf4ee2e4dc7beac Mon Sep 17 00:00:00 2001 From: Tim Fischer Date: Wed, 4 Oct 2023 11:19:18 +0200 Subject: [PATCH 11/13] sim: Update wave scripts --- test/tb_floo_axi_chimney.wave.tcl | 6 ++++-- test/tb_floo_narrow_wide_chimney.wave.tcl | 19 +++++++++++++++++-- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/test/tb_floo_axi_chimney.wave.tcl b/test/tb_floo_axi_chimney.wave.tcl index a193e9b3..89b19b90 100644 --- a/test/tb_floo_axi_chimney.wave.tcl +++ b/test/tb_floo_axi_chimney.wave.tcl @@ -34,8 +34,10 @@ 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 {$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/* 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] From c137b2baf8404888ea7da511f81b52c3c38f2483 Mon Sep 17 00:00:00 2001 From: Tim Fischer Date: Wed, 4 Oct 2023 11:23:31 +0200 Subject: [PATCH 12/13] lint: System Verilog sources --- src/floo_meta_buffer.sv | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/floo_meta_buffer.sv b/src/floo_meta_buffer.sv index 364a7fc2..27edf506 100644 --- a/src/floo_meta_buffer.sv +++ b/src/floo_meta_buffer.sv @@ -103,7 +103,8 @@ module floo_meta_buffer #( 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!") + `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; @@ -175,9 +176,11 @@ module floo_meta_buffer #( 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; + 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; + 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 @@ -188,8 +191,10 @@ module floo_meta_buffer #( 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_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)? From 938a73d314d941893ce63dddafcea4748d753448 Mon Sep 17 00:00:00 2001 From: Tim Fischer Date: Wed, 4 Oct 2023 16:37:50 +0200 Subject: [PATCH 13/13] Update CHANGELOG --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) 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