Skip to content

Commit

Permalink
hw: Fixes for elaboration (#75)
Browse files Browse the repository at this point in the history
* floogen(routing): Render unused routes as zeros

* hw(meta_buf): Fix signal names

* hw(nw_chimney): Fix elab errors

* hw(chimney): Use generate loop over `route_comp` modules instead of module arrays

* lint: SV sources

* docs: Update CHANGELOG
  • Loading branch information
fischeti authored Oct 3, 2024
1 parent b6a816f commit 944e529
Show file tree
Hide file tree
Showing 6 changed files with 191 additions and 127 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
4 changes: 2 additions & 2 deletions floogen/model/routing.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
101 changes: 62 additions & 39 deletions hw/floo_axi_chimney.sv
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
8 changes: 4 additions & 4 deletions hw/floo_meta_buffer.sv
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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 #(
Expand Down Expand Up @@ -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!")
Expand Down
102 changes: 61 additions & 41 deletions hw/floo_nw_chimney.sv
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
102 changes: 61 additions & 41 deletions hw/floo_nw_vc_chimney.sv
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 944e529

Please sign in to comment.