diff --git a/CHANGELOG.md b/CHANGELOG.md index 5826d6b0..ca67d054 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -52,6 +52,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) - A bug in the calcuation of the RoB offset in `floo_rob` was fixed. Previously, the allocation and the write process used the same counter in bursts for offset calculation, which resulted in wrong offsets. - Routers with `XYRouting` do now use the global `id_offset`, which was previously not accounted for (or had to be specified manually). +- Fixed elaboration errors in the chimneys that occured. ### Removed diff --git a/floogen/model/routing.py b/floogen/model/routing.py index f5ab33ba..25707a2d 100644 --- a/floogen/model/routing.py +++ b/floogen/model/routing.py @@ -265,8 +265,8 @@ def render(self, num_route_bits): split_route = False if self.route is None: if split_route: - return f"{num_route_bits}'d?" - return f"{num_route_bits}'b{'?' * num_route_bits}" + return f"{num_route_bits}'d0" + return f"{num_route_bits}'b{'0' * num_route_bits}" for port, num_bits in self.route: if split_route: route_str = f"{num_bits}'d{port}, " + route_str diff --git a/hw/floo_axi_chimney.sv b/hw/floo_axi_chimney.sv index 0aa937f8..61d3f705 100644 --- a/hw/floo_axi_chimney.sv +++ b/hw/floo_axi_chimney.sv @@ -374,49 +374,72 @@ module floo_axi_chimney #( // ROUTING // ///////////////// - floo_route_comp #( - .RouteCfg ( RouteCfg ), - .id_t ( id_t ), - .addr_t ( axi_addr_t ), - .addr_rule_t ( sam_rule_t ), - .route_t ( route_t ) - ) i_floo_req_route_comp [1:0] ( - .clk_i, - .rst_ni, - .route_table_i, - .addr_map_i ( Sam ), - .id_i ( id_t'('0) ), - .addr_i ( {axi_aw_queue.addr, axi_ar_queue.addr} ), - .route_o ( {route_out[AxiAw], route_out[AxiAr]} ), - .id_o ( {id_out[AxiAw], id_out[AxiAr]} ) - ); - if (RouteCfg.RouteAlgo == SourceRouting) begin : gen_route_field - floo_route_comp #( - .RouteCfg ( RouteCfg ), - .UseIdTable ( 1'b0 ), // Overwrite RouteCfg - .id_t ( id_t ), - .addr_t ( axi_addr_t ), - .addr_rule_t ( sam_rule_t ), - .route_t ( route_t ) - ) i_floo_rsp_route_comp [1:0] ( - .clk_i, - .rst_ni, - .route_table_i, - .addr_i ( '0 ), - .addr_map_i ( '0 ), - .id_i ({aw_out_hdr_out.hdr.src_id, ar_out_hdr_out.hdr.src_id} ), - .route_o ({route_out[AxiB], route_out[AxiR]} ), - .id_o ({id_out[AxiB], id_out[AxiR]} ) - ); + axi_addr_t [NumAxiChannels-1:0] axi_req_addr; + id_t [NumAxiChannels-1:0] axi_rsp_src_id; + + assign axi_req_addr[AxiAw] = axi_aw_queue.addr; + assign axi_req_addr[AxiAr] = axi_ar_queue.addr; + + assign axi_rsp_src_id[AxiB] = aw_out_hdr_out.hdr.src_id; + assign axi_rsp_src_id[AxiR] = ar_out_hdr_out.hdr.src_id; + + for (genvar ch = 0; ch < NumAxiChannels; ch++) begin : gen_route_comp + localparam axi_ch_e Ch = axi_ch_e'(ch); + if (Ch == AxiAw || Ch == AxiAr) begin : gen_req_route_comp + // Translate the address from AXI requests to a destination ID + // (or route if `SourceRouting` is used) + floo_route_comp #( + .RouteCfg ( RouteCfg ), + .id_t ( id_t ), + .addr_t ( axi_addr_t ), + .addr_rule_t ( sam_rule_t ), + .route_t ( route_t ) + ) i_floo_req_route_comp ( + .clk_i, + .rst_ni, + .route_table_i, + .addr_map_i ( Sam ), + .id_i ( id_t'('0) ), + .addr_i ( axi_req_addr[ch] ), + .route_o ( route_out[ch] ), + .id_o ( id_out[ch] ) + ); + end else if (RouteCfg.RouteAlgo == floo_pkg::SourceRouting && + (Ch == AxiB || Ch == AxiR)) begin : gen_rsp_route_comp + // Generally, the source ID from the request is used to route back + // the responses. However, in the case of `SourceRouting`, the source ID + // first needs to be translated into a route. + floo_route_comp #( + .RouteCfg ( RouteCfg ), + .UseIdTable ( 1'b0 ), // Overwrite `RouteCfg` + .id_t ( id_t ), + .addr_t ( axi_addr_t ), + .addr_rule_t ( sam_rule_t ), + .route_t ( route_t ) + ) i_floo_rsp_route_comp ( + .clk_i, + .rst_ni, + .route_table_i, + .addr_i ( '0 ), + .addr_map_i ( '0 ), + .id_i ( axi_rsp_src_id[ch] ), + .route_o ( route_out[ch] ), + .id_o ( id_out[ch] ) + ); + end + end + + if (RouteCfg.RouteAlgo == floo_pkg::SourceRouting) begin : gen_route_field assign route_out[AxiW] = axi_aw_id_q; assign dst_id = route_out; end else begin : gen_dst_field - assign dst_id[AxiAw] = id_out[AxiAw]; - assign dst_id[AxiAr] = id_out[AxiAr]; - assign dst_id[AxiB] = aw_out_hdr_out.hdr.src_id; - assign dst_id[AxiR] = ar_out_hdr_out.hdr.src_id; - assign dst_id[AxiW] = axi_aw_id_q; + assign dst_id[AxiAw] = id_out[AxiAw]; + assign dst_id[AxiAr] = id_out[AxiAr]; + assign dst_id[AxiB] = aw_out_hdr_out.hdr.src_id; + assign dst_id[AxiR] = ar_out_hdr_out.hdr.src_id; + assign dst_id[AxiW] = axi_aw_id_q; end + `FFL(axi_aw_id_q, dst_id[AxiAw], axi_aw_queue_valid_out && axi_aw_queue_ready_in, '0) diff --git a/hw/floo_meta_buffer.sv b/hw/floo_meta_buffer.sv index 0b686136..8bfdf032 100644 --- a/hw/floo_meta_buffer.sv +++ b/hw/floo_meta_buffer.sv @@ -109,8 +109,8 @@ module floo_meta_buffer #( end else begin : gen_no_atop_id_queue - logic b_outp_gnt, b_oup_data_valid; - logic r_outp_gnt, r_oup_data_valid; + logic b_oup_gnt, b_oup_data_valid; + logic r_oup_gnt, r_oup_data_valid; id_out_t no_atop_aw_req_id_in, no_atop_ar_req_id_in; @@ -146,7 +146,7 @@ module floo_meta_buffer #( .oup_req_i ( axi_rsp_i.b_valid ), .oup_data_o ( no_atop_b_buf ), .oup_data_valid_o ( b_oup_data_valid ), - .oup_gnt_o ( b_outp_gnt ) + .oup_gnt_o ( b_oup_gnt ) ); id_queue #( @@ -177,7 +177,7 @@ module floo_meta_buffer #( assign ar_no_atop_buf_full = !ar_no_atop_buf_not_full; assign aw_no_atop_buf_full = !aw_no_atop_buf_not_full; - `ASSERT(NoBResponseIdQueue, axi_rsp_i.b_valid -> (b_oup_data_valid && b_outp_gnt), + `ASSERT(NoBResponseIdQueue, axi_rsp_i.b_valid -> (b_oup_data_valid && b_oup_gnt), "Meta data for B response must exist in Id Queue!") `ASSERT(NoRResponseIdQueue, axi_rsp_i.r_valid -> (r_oup_data_valid && r_oup_gnt), "Meta data for R response must exist in Id Queue!") diff --git a/hw/floo_nw_chimney.sv b/hw/floo_nw_chimney.sv index c8a3bf97..13977239 100644 --- a/hw/floo_nw_chimney.sv +++ b/hw/floo_nw_chimney.sv @@ -631,49 +631,69 @@ module floo_nw_chimney #( // ROUTING // ///////////////// - typedef axi_addr_t addr_t; - - floo_route_comp #( - .RouteCfg ( RouteCfg ), - .id_t ( id_t ), - .addr_t ( addr_t ), - .addr_rule_t ( sam_rule_t ), - .route_t ( route_t ) - ) i_floo_req_route_comp [3:0] ( - .clk_i, - .rst_ni, - .route_table_i, - .addr_map_i ( Sam ), - .id_i ( id_t'('0) ), - .addr_i ({ - axi_narrow_aw_queue.addr, axi_narrow_ar_queue.addr, - axi_wide_aw_queue.addr, axi_wide_ar_queue.addr - }), - .route_o ({route_out[NarrowAw], route_out[NarrowAr], route_out[WideAw], route_out[WideAr]} ), - .id_o ({id_out[NarrowAw], id_out[NarrowAr],id_out[WideAw], id_out[WideAr]} ) - ); + axi_addr_t [NumNWAxiChannels-1:0] axi_req_addr; + id_t [NumNWAxiChannels-1:0] axi_rsp_src_id; + + assign axi_req_addr[NarrowAw] = axi_narrow_aw_queue.addr; + assign axi_req_addr[NarrowAr] = axi_narrow_ar_queue.addr; + assign axi_req_addr[WideAw] = axi_wide_aw_queue.addr; + assign axi_req_addr[WideAr] = axi_wide_ar_queue.addr; + + assign axi_rsp_src_id[NarrowB] = narrow_aw_buf_hdr_out.hdr.src_id; + assign axi_rsp_src_id[NarrowR] = narrow_ar_buf_hdr_out.hdr.src_id; + assign axi_rsp_src_id[WideB] = wide_aw_buf_hdr_out.hdr.src_id; + assign axi_rsp_src_id[WideR] = wide_ar_buf_hdr_out.hdr.src_id; + + for (genvar ch = 0; ch < NumNWAxiChannels; ch++) begin : gen_route_comp + localparam nw_ch_e Ch = nw_ch_e'(ch); + if (Ch == NarrowAw || Ch == NarrowAr || + Ch == WideAw || Ch == WideAr) begin : gen_req_route_comp + + // Translate the address from AXI requests to a destination ID + // (or route if `SourceRouting` is used) + floo_route_comp #( + .RouteCfg ( RouteCfg ), + .id_t ( id_t ), + .addr_t ( axi_addr_t ), + .addr_rule_t ( sam_rule_t ), + .route_t ( route_t ) + ) i_floo_req_route_comp ( + .clk_i, + .rst_ni, + .route_table_i, + .addr_map_i ( Sam ), + .id_i ( id_t'('0) ), + .addr_i ( axi_req_addr[ch] ), + .route_o ( route_out[ch] ), + .id_o ( id_out[ch] ) + ); + end else if (RouteCfg.RouteAlgo == floo_pkg::SourceRouting && + (Ch == NarrowB || Ch == NarrowR || + Ch == WideB || Ch == WideR)) begin : gen_rsp_route_comp + // Generally, the source ID from the request is used to route back + // the responses. However, in the case of `SourceRouting`, the source ID + // first needs to be translated into a route. + floo_route_comp #( + .RouteCfg ( RouteCfg ), + .UseIdTable ( 1'b0 ), // Overwrite `RouteCfg` + .id_t ( id_t ), + .addr_t ( axi_addr_t ), + .addr_rule_t ( sam_rule_t ), + .route_t ( route_t ) + ) i_floo_rsp_route_comp ( + .clk_i, + .rst_ni, + .route_table_i, + .addr_i ( '0 ), + .addr_map_i ( '0 ), + .id_i ( axi_rsp_src_id[ch] ), + .route_o ( route_out[ch] ), + .id_o ( id_out[ch] ) + ); + end + end if (RouteCfg.RouteAlgo == floo_pkg::SourceRouting) begin : gen_route_field - floo_route_comp #( - .RouteCfg ( RouteCfg ), - .UseIdTable ( 1'b0 ), // Overwrite `RouteCfg` - .id_t ( id_t ), - .addr_t ( addr_t ), - .addr_rule_t ( sam_rule_t ), - .route_t ( route_t ) - ) i_floo_rsp_route_comp [3:0] ( - .clk_i, - .rst_ni, - .route_table_i, - .addr_i ( '0 ), - .addr_map_i ( '0 ), - .id_i ({ - narrow_aw_buf_hdr_out.hdr.src_id, narrow_ar_buf_hdr_out.hdr.src_id, - wide_aw_buf_hdr_out.hdr.src_id, wide_ar_buf_hdr_out.hdr.src_id - }), - .route_o ({route_out[NarrowB], route_out[NarrowR], route_out[WideB], route_out[WideR]} ), - .id_o ({id_out[NarrowB], id_out[NarrowR], id_out[WideB], id_out[WideR]} ) - ); assign route_out[NarrowW] = narrow_aw_id_q; assign route_out[WideW] = wide_aw_id_q; assign dst_id = route_out; diff --git a/hw/floo_nw_vc_chimney.sv b/hw/floo_nw_vc_chimney.sv index 79631d90..4a3d8ce9 100644 --- a/hw/floo_nw_vc_chimney.sv +++ b/hw/floo_nw_vc_chimney.sv @@ -679,49 +679,69 @@ module floo_nw_vc_chimney #( // ROUTING // ///////////////// - typedef axi_addr_t addr_t; - - floo_route_comp #( - .RouteCfg ( RouteCfg ), - .id_t ( id_t ), - .addr_t ( addr_t ), - .addr_rule_t ( sam_rule_t ), - .route_t ( route_t ) - ) i_floo_req_route_comp [3:0] ( - .clk_i, - .rst_ni, - .route_table_i, - .addr_map_i ( Sam ), - .id_i ( '0 ), - .addr_i ({ - axi_narrow_aw_queue.addr, axi_narrow_ar_queue.addr, - axi_wide_aw_queue.addr, axi_wide_ar_queue.addr - }), - .route_o ({route_out[NarrowAw], route_out[NarrowAr], route_out[WideAw], route_out[WideAr]} ), - .id_o ({id_out[NarrowAw], id_out[NarrowAr],id_out[WideAw], id_out[WideAr]} ) - ); + axi_addr_t [NumNWAxiChannels-1:0] axi_req_addr; + id_t [NumNWAxiChannels-1:0] axi_rsp_src_id; + + assign axi_req_addr[NarrowAw] = axi_narrow_aw_queue.addr; + assign axi_req_addr[NarrowAr] = axi_narrow_ar_queue.addr; + assign axi_req_addr[WideAw] = axi_wide_aw_queue.addr; + assign axi_req_addr[WideAr] = axi_wide_ar_queue.addr; + + assign axi_rsp_src_id[NarrowB] = narrow_aw_buf_hdr_out.hdr.src_id; + assign axi_rsp_src_id[NarrowR] = narrow_ar_buf_hdr_out.hdr.src_id; + assign axi_rsp_src_id[WideB] = wide_aw_buf_hdr_out.hdr.src_id; + assign axi_rsp_src_id[WideR] = wide_ar_buf_hdr_out.hdr.src_id; + + for (genvar ch = 0; ch < NumNWAxiChannels; ch++) begin : gen_route_comp + localparam nw_ch_e Ch = nw_ch_e'(ch); + if (Ch == NarrowAw || Ch == NarrowAr || + Ch == WideAw || Ch == WideAr) begin : gen_req_route_comp + + // Translate the address from AXI requests to a destination ID + // (or route if `SourceRouting` is used) + floo_route_comp #( + .RouteCfg ( RouteCfg ), + .id_t ( id_t ), + .addr_t ( axi_addr_t ), + .addr_rule_t ( sam_rule_t ), + .route_t ( route_t ) + ) i_floo_req_route_comp ( + .clk_i, + .rst_ni, + .route_table_i, + .addr_map_i ( Sam ), + .id_i ( id_t'('0) ), + .addr_i ( axi_req_addr[ch] ), + .route_o ( route_out[ch] ), + .id_o ( id_out[ch] ) + ); + end else if (RouteCfg.RouteAlgo == floo_pkg::SourceRouting && + (Ch == NarrowB || Ch == NarrowR || + Ch == WideB || Ch == WideR)) begin : gen_rsp_route_comp + // Generally, the source ID from the request is used to route back + // the responses. However, in the case of `SourceRouting`, the source ID + // first needs to be translated into a route. + floo_route_comp #( + .RouteCfg ( RouteCfg ), + .UseIdTable ( 1'b0 ), // Overwrite `RouteCfg` + .id_t ( id_t ), + .addr_t ( axi_addr_t ), + .addr_rule_t ( sam_rule_t ), + .route_t ( route_t ) + ) i_floo_rsp_route_comp ( + .clk_i, + .rst_ni, + .route_table_i, + .addr_i ( '0 ), + .addr_map_i ( '0 ), + .id_i ( axi_rsp_src_id[ch] ), + .route_o ( route_out[ch] ), + .id_o ( id_out[ch] ) + ); + end + end if (RouteCfg.RouteAlgo == floo_pkg::SourceRouting) begin : gen_route_field - floo_route_comp #( - .RouteCfg ( RouteCfg ), - .UseIdTable ( 1'b0 ), // Overwrite `RouteCfg` - .id_t ( id_t ), - .addr_t ( addr_t ), - .addr_rule_t ( sam_rule_t ), - .route_t ( route_t ) - ) i_floo_rsp_route_comp [3:0] ( - .clk_i, - .rst_ni, - .route_table_i, - .addr_i ( '0 ), - .addr_map_i ( '0 ), - .id_i ({ - narrow_aw_buf_hdr_out.hdr.src_id, narrow_ar_buf_hdr_out.hdr.src_id, - wide_aw_buf_hdr_out.hdr.src_id, wide_ar_buf_hdr_out.hdr.src_id - }), - .route_o ({route_out[NarrowB], route_out[NarrowR], route_out[WideB], route_out[WideR]} ), - .id_o ({id_out[NarrowB], id_out[NarrowR], id_out[WideB], id_out[WideR]} ) - ); assign route_out[NarrowW] = narrow_aw_id_q; assign route_out[WideW] = wide_aw_id_q; assign dst_id = route_out;