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/*