Skip to content

Commit

Permalink
Merge pull request #225 from pulp-platform/fix-demux-mux-single-port-…
Browse files Browse the repository at this point in the history
…spill-regs

axi_{,lite_}{,de}mux: Add missing spill registers for single master/slave port configurations
  • Loading branch information
andreaskurth authored Mar 31, 2022
2 parents d9acde3 + b91f440 commit 5a5d5e5
Show file tree
Hide file tree
Showing 5 changed files with 280 additions and 9 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
### Changed

### Fixed
- `axi_demux` and `axi_lite_demux`: Add missing spill registers for configurations with a single
master port.
- `axi_demux_intf`: Add missing parameter (`ATOP_SUPPORT`) to optionally disable support for atomic
operations.
- `axi_mux` and `axi_lite_mux`: Add missing spill registers for configurations with a single slave
port.
- `axi_lite_mux_intf`: Add missing parameter values on the internal `axi_lite_mux` instance
(`axi_req_t` and `axi_resp_t`).
- `axi_sim_mem`: Propagate the AR channel's user signal correctly to the monitor.
Expand Down
68 changes: 66 additions & 2 deletions src/axi_demux.sv
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,72 @@ module axi_demux #(

// pass through if only one master port
if (NoMstPorts == 32'h1) begin : gen_no_demux
assign mst_reqs_o[0] = slv_req_i;
assign slv_resp_o = mst_resps_i;
spill_register #(
.T ( aw_chan_t ),
.Bypass ( ~SpillAw )
) i_aw_spill_reg (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.valid_i ( slv_req_i.aw_valid ),
.ready_o ( slv_resp_o.aw_ready ),
.data_i ( slv_req_i.aw ),
.valid_o ( mst_reqs_o[0].aw_valid ),
.ready_i ( mst_resps_i[0].aw_ready ),
.data_o ( mst_reqs_o[0].aw )
);
spill_register #(
.T ( w_chan_t ),
.Bypass ( ~SpillW )
) i_w_spill_reg (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.valid_i ( slv_req_i.w_valid ),
.ready_o ( slv_resp_o.w_ready ),
.data_i ( slv_req_i.w ),
.valid_o ( mst_reqs_o[0].w_valid ),
.ready_i ( mst_resps_i[0].w_ready ),
.data_o ( mst_reqs_o[0].w )
);
spill_register #(
.T ( b_chan_t ),
.Bypass ( ~SpillB )
) i_b_spill_reg (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.valid_i ( mst_resps_i[0].b_valid ),
.ready_o ( mst_reqs_o[0].b_ready ),
.data_i ( mst_resps_i[0].b ),
.valid_o ( slv_resp_o.b_valid ),
.ready_i ( slv_req_i.b_ready ),
.data_o ( slv_resp_o.b )
);
spill_register #(
.T ( ar_chan_t ),
.Bypass ( ~SpillAr )
) i_ar_spill_reg (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.valid_i ( slv_req_i.ar_valid ),
.ready_o ( slv_resp_o.ar_ready ),
.data_i ( slv_req_i.ar ),
.valid_o ( mst_reqs_o[0].ar_valid ),
.ready_i ( mst_resps_i[0].ar_ready ),
.data_o ( mst_reqs_o[0].ar )
);
spill_register #(
.T ( r_chan_t ),
.Bypass ( ~SpillR )
) i_r_spill_reg (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.valid_i ( mst_resps_i[0].r_valid ),
.ready_o ( mst_reqs_o[0].r_ready ),
.data_i ( mst_resps_i[0].r ),
.valid_o ( slv_resp_o.r_valid ),
.ready_i ( slv_req_i.r_ready ),
.data_o ( slv_resp_o.r )
);

// other non degenerate cases
end else begin : gen_demux

Expand Down
69 changes: 66 additions & 3 deletions src/axi_lite_demux.sv
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,72 @@ module axi_lite_demux #(

if (NoMstPorts == 32'd1) begin : gen_no_demux
// degenerate case, connect slave to master port
// AW channel
assign mst_reqs_o[0] = slv_req_i;
assign slv_resp_o = mst_resps_i[0];
spill_register #(
.T ( aw_chan_t ),
.Bypass ( ~SpillAw )
) i_aw_spill_reg (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.valid_i ( slv_req_i.aw_valid ),
.ready_o ( slv_resp_o.aw_ready ),
.data_i ( slv_req_i.aw ),
.valid_o ( mst_reqs_o[0].aw_valid ),
.ready_i ( mst_resps_i[0].aw_ready ),
.data_o ( mst_reqs_o[0].aw )
);
spill_register #(
.T ( w_chan_t ),
.Bypass ( ~SpillW )
) i_w_spill_reg (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.valid_i ( slv_req_i.w_valid ),
.ready_o ( slv_resp_o.w_ready ),
.data_i ( slv_req_i.w ),
.valid_o ( mst_reqs_o[0].w_valid ),
.ready_i ( mst_resps_i[0].w_ready ),
.data_o ( mst_reqs_o[0].w )
);
spill_register #(
.T ( b_chan_t ),
.Bypass ( ~SpillB )
) i_b_spill_reg (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.valid_i ( mst_resps_i[0].b_valid ),
.ready_o ( mst_reqs_o[0].b_ready ),
.data_i ( mst_resps_i[0].b ),
.valid_o ( slv_resp_o.b_valid ),
.ready_i ( slv_req_i.b_ready ),
.data_o ( slv_resp_o.b )
);
spill_register #(
.T ( ar_chan_t ),
.Bypass ( ~SpillAr )
) i_ar_spill_reg (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.valid_i ( slv_req_i.ar_valid ),
.ready_o ( slv_resp_o.ar_ready ),
.data_i ( slv_req_i.ar ),
.valid_o ( mst_reqs_o[0].ar_valid ),
.ready_i ( mst_resps_i[0].ar_ready ),
.data_o ( mst_reqs_o[0].ar )
);
spill_register #(
.T ( r_chan_t ),
.Bypass ( ~SpillR )
) i_r_spill_reg (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.valid_i ( mst_resps_i[0].r_valid ),
.ready_o ( mst_reqs_o[0].r_ready ),
.data_i ( mst_resps_i[0].r ),
.valid_o ( slv_resp_o.r_valid ),
.ready_i ( slv_req_i.r_ready ),
.data_o ( slv_resp_o.r )
);

end else begin : gen_demux
// normal non degenerate case

Expand Down
68 changes: 66 additions & 2 deletions src/axi_lite_mux.sv
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,72 @@ module axi_lite_mux #(
);
// pass through if only one slave port
if (NoSlvPorts == 32'h1) begin : gen_no_mux
assign mst_req_o = slv_reqs_i[0];
assign slv_resps_o[0] = mst_resp_i;
spill_register #(
.T ( aw_chan_t ),
.Bypass ( ~SpillAw )
) i_aw_spill_reg (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.valid_i ( slv_reqs_i[0].aw_valid ),
.ready_o ( slv_resps_o[0].aw_ready ),
.data_i ( slv_reqs_i[0].aw ),
.valid_o ( mst_req_o.aw_valid ),
.ready_i ( mst_resp_i.aw_ready ),
.data_o ( mst_req_o.aw )
);
spill_register #(
.T ( w_chan_t ),
.Bypass ( ~SpillW )
) i_w_spill_reg (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.valid_i ( slv_reqs_i[0].w_valid ),
.ready_o ( slv_resps_o[0].w_ready ),
.data_i ( slv_reqs_i[0].w ),
.valid_o ( mst_req_o.w_valid ),
.ready_i ( mst_resp_i.w_ready ),
.data_o ( mst_req_o.w )
);
spill_register #(
.T ( b_chan_t ),
.Bypass ( ~SpillB )
) i_b_spill_reg (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.valid_i ( mst_resp_i.b_valid ),
.ready_o ( mst_req_o.b_ready ),
.data_i ( mst_resp_i.b ),
.valid_o ( slv_resps_o[0].b_valid ),
.ready_i ( slv_reqs_i[0].b_ready ),
.data_o ( slv_resps_o[0].b )
);
spill_register #(
.T ( ar_chan_t ),
.Bypass ( ~SpillAr )
) i_ar_spill_reg (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.valid_i ( slv_reqs_i[0].ar_valid ),
.ready_o ( slv_resps_o[0].ar_ready ),
.data_i ( slv_reqs_i[0].ar ),
.valid_o ( mst_req_o.ar_valid ),
.ready_i ( mst_resp_i.ar_ready ),
.data_o ( mst_req_o.ar )
);
spill_register #(
.T ( r_chan_t ),
.Bypass ( ~SpillR )
) i_r_spill_reg (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.valid_i ( mst_resp_i.r_valid ),
.ready_o ( mst_req_o.r_ready ),
.data_i ( mst_resp_i.r ),
.valid_o ( slv_resps_o[0].r_valid ),
.ready_i ( slv_reqs_i[0].r_ready ),
.data_o ( slv_resps_o[0].r )
);

// other non degenerate cases
end else begin : gen_mux
// typedef for the FIFO types
Expand Down
80 changes: 78 additions & 2 deletions src/axi_mux.sv
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
// a response with ID `6'b100110` will be forwarded to slave port 2 (`2'b10`).

// register macros
`include "common_cells/assertions.svh"
`include "common_cells/registers.svh"

module axi_mux #(
Expand Down Expand Up @@ -69,8 +70,83 @@ module axi_mux #(

// pass through if only one slave port
if (NoSlvPorts == 32'h1) begin : gen_no_mux
assign mst_req_o = slv_reqs_i[0];
assign slv_resps_o[0] = mst_resp_i;
spill_register #(
.T ( mst_aw_chan_t ),
.Bypass ( ~SpillAw )
) i_aw_spill_reg (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.valid_i ( slv_reqs_i[0].aw_valid ),
.ready_o ( slv_resps_o[0].aw_ready ),
.data_i ( slv_reqs_i[0].aw ),
.valid_o ( mst_req_o.aw_valid ),
.ready_i ( mst_resp_i.aw_ready ),
.data_o ( mst_req_o.aw )
);
spill_register #(
.T ( w_chan_t ),
.Bypass ( ~SpillW )
) i_w_spill_reg (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.valid_i ( slv_reqs_i[0].w_valid ),
.ready_o ( slv_resps_o[0].w_ready ),
.data_i ( slv_reqs_i[0].w ),
.valid_o ( mst_req_o.w_valid ),
.ready_i ( mst_resp_i.w_ready ),
.data_o ( mst_req_o.w )
);
spill_register #(
.T ( mst_b_chan_t ),
.Bypass ( ~SpillB )
) i_b_spill_reg (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.valid_i ( mst_resp_i.b_valid ),
.ready_o ( mst_req_o.b_ready ),
.data_i ( mst_resp_i.b ),
.valid_o ( slv_resps_o[0].b_valid ),
.ready_i ( slv_reqs_i[0].b_ready ),
.data_o ( slv_resps_o[0].b )
);
spill_register #(
.T ( mst_ar_chan_t ),
.Bypass ( ~SpillAr )
) i_ar_spill_reg (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.valid_i ( slv_reqs_i[0].ar_valid ),
.ready_o ( slv_resps_o[0].ar_ready ),
.data_i ( slv_reqs_i[0].ar ),
.valid_o ( mst_req_o.ar_valid ),
.ready_i ( mst_resp_i.ar_ready ),
.data_o ( mst_req_o.ar )
);
spill_register #(
.T ( mst_r_chan_t ),
.Bypass ( ~SpillR )
) i_r_spill_reg (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.valid_i ( mst_resp_i.r_valid ),
.ready_o ( mst_req_o.r_ready ),
.data_i ( mst_resp_i.r ),
.valid_o ( slv_resps_o[0].r_valid ),
.ready_i ( slv_reqs_i[0].r_ready ),
.data_o ( slv_resps_o[0].r )
);
// Validate parameters.
// pragma translate_off
`ASSERT_INIT(CorrectIdWidthSlvAw, $bits(slv_reqs_i[0].aw.id) == SlvAxiIDWidth)
`ASSERT_INIT(CorrectIdWidthSlvB, $bits(slv_resps_o[0].b.id) == SlvAxiIDWidth)
`ASSERT_INIT(CorrectIdWidthSlvAr, $bits(slv_reqs_i[0].ar.id) == SlvAxiIDWidth)
`ASSERT_INIT(CorrectIdWidthSlvR, $bits(slv_resps_o[0].r.id) == SlvAxiIDWidth)
`ASSERT_INIT(CorrectIdWidthMstAw, $bits(mst_req_o.aw.id) == SlvAxiIDWidth)
`ASSERT_INIT(CorrectIdWidthMstB, $bits(mst_resp_i.b.id) == SlvAxiIDWidth)
`ASSERT_INIT(CorrectIdWidthMstAr, $bits(mst_req_o.ar.id) == SlvAxiIDWidth)
`ASSERT_INIT(CorrectIdWidthMstR, $bits(mst_resp_i.r.id) == SlvAxiIDWidth)
// pragma translate_on

// other non degenerate cases
end else begin : gen_mux

Expand Down

0 comments on commit 5a5d5e5

Please sign in to comment.