From c63448ce94dda8d85434cd4f421c9d0b92e8f5d3 Mon Sep 17 00:00:00 2001 From: Tim Fischer Date: Wed, 27 Sep 2023 15:54:36 +0200 Subject: [PATCH] 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 ),