-
Notifications
You must be signed in to change notification settings - Fork 273
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Removes demux and mux inside
- Loading branch information
Showing
1 changed file
with
111 additions
and
189 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,7 @@ | |
// Authors: | ||
// - Andreas Kurth <[email protected]> | ||
// - Paul Scheffler <[email protected]> | ||
// - Michael Rogenmoser <[email protected]> | ||
|
||
`include "axi/assign.svh" | ||
`include "axi/typedef.svh" | ||
|
@@ -90,70 +91,9 @@ module axi_id_serialize #( | |
/// ID width after the multiplexer | ||
localparam int unsigned MuxIdWidth = (AxiMstPortMaxUniqIds > 32'd1) ? SelectWidth + 32'd1 : 32'd1; | ||
|
||
/// ID after serializer (i.e., with a constant value of zero) | ||
typedef logic [0:0] ser_id_t; | ||
/// ID after the multiplexer | ||
typedef logic [MuxIdWidth-1:0] mux_id_t; | ||
/// ID at the slave port | ||
typedef logic [AxiSlvPortIdWidth-1:0] slv_id_t; | ||
/// ID at the master port | ||
typedef logic [AxiMstPortIdWidth-1:0] mst_id_t; | ||
/// Address in any AXI channel | ||
typedef logic [AxiAddrWidth-1:0] addr_t; | ||
/// Data in any AXI channel | ||
typedef logic [AxiDataWidth-1:0] data_t; | ||
/// Strobe in any AXI channel | ||
typedef logic [AxiDataWidth/8-1:0] strb_t; | ||
/// User signal in any AXI channel | ||
typedef logic [AxiUserWidth-1:0] user_t; | ||
|
||
/// W channel at any interface | ||
`AXI_TYPEDEF_W_CHAN_T(w_t, data_t, strb_t, user_t) | ||
|
||
/// AW channel at slave port | ||
`AXI_TYPEDEF_AW_CHAN_T(slv_aw_t, addr_t, slv_id_t, user_t) | ||
/// B channel at slave port | ||
`AXI_TYPEDEF_B_CHAN_T(slv_b_t, slv_id_t, user_t) | ||
/// AR channel at slave port | ||
`AXI_TYPEDEF_AR_CHAN_T(slv_ar_t, addr_t, slv_id_t, user_t) | ||
/// R channel at slave port | ||
`AXI_TYPEDEF_R_CHAN_T(slv_r_t, data_t, slv_id_t, user_t) | ||
|
||
/// AW channel after serializer | ||
`AXI_TYPEDEF_AW_CHAN_T(ser_aw_t, addr_t, ser_id_t, user_t) | ||
/// B channel after serializer | ||
`AXI_TYPEDEF_B_CHAN_T(ser_b_t, ser_id_t, user_t) | ||
/// AR channel after serializer | ||
`AXI_TYPEDEF_AR_CHAN_T(ser_ar_t, addr_t, ser_id_t, user_t) | ||
/// R channel after serializer | ||
`AXI_TYPEDEF_R_CHAN_T(ser_r_t, data_t, ser_id_t, user_t) | ||
/// AXI Requests from serializer | ||
`AXI_TYPEDEF_REQ_T(ser_req_t, ser_aw_t, w_t, ser_ar_t) | ||
/// AXI responses to serializer | ||
`AXI_TYPEDEF_RESP_T(ser_resp_t, ser_b_t, ser_r_t) | ||
|
||
/// AW channel after the multiplexer | ||
`AXI_TYPEDEF_AW_CHAN_T(mux_aw_t, addr_t, mux_id_t, user_t) | ||
/// B channel after the multiplexer | ||
`AXI_TYPEDEF_B_CHAN_T(mux_b_t, mux_id_t, user_t) | ||
/// AR channel after the multiplexer | ||
`AXI_TYPEDEF_AR_CHAN_T(mux_ar_t, addr_t, mux_id_t, user_t) | ||
/// R channel after the multiplexer | ||
`AXI_TYPEDEF_R_CHAN_T(mux_r_t, data_t, mux_id_t, user_t) | ||
/// AXI requests from the multiplexer | ||
`AXI_TYPEDEF_REQ_T(mux_req_t, mux_aw_t, w_t, mux_ar_t) | ||
/// AXI responses to the multiplexer | ||
`AXI_TYPEDEF_RESP_T(mux_resp_t, mux_b_t, mux_r_t) | ||
|
||
/// AW channel at master port | ||
`AXI_TYPEDEF_AW_CHAN_T(mst_aw_t, addr_t, mst_id_t, user_t) | ||
/// B channel at master port | ||
`AXI_TYPEDEF_B_CHAN_T(mst_b_t, mst_id_t, user_t) | ||
/// AR channel at master port | ||
`AXI_TYPEDEF_AR_CHAN_T(mst_ar_t, addr_t, mst_id_t, user_t) | ||
/// R channel at master port | ||
`AXI_TYPEDEF_R_CHAN_T(mst_r_t, data_t, mst_id_t, user_t) | ||
|
||
|
||
/// Type for slave ID map | ||
typedef mst_id_t [2**AxiSlvPortIdWidth-1:0] slv_id_map_t; | ||
|
||
|
@@ -172,49 +112,70 @@ module axi_id_serialize #( | |
/// Input-to-output ID map used | ||
localparam slv_id_map_t SlvIdMap = map_slv_ids(); | ||
|
||
select_t slv_aw_select, slv_ar_select; | ||
select_t slv_aw_select, slv_ar_select, slv_w_select, slv_b_select, slv_r_select; | ||
assign slv_aw_select = select_t'(SlvIdMap[slv_req_i.aw.id]); | ||
assign slv_ar_select = select_t'(SlvIdMap[slv_req_i.ar.id]); | ||
|
||
slv_req_t [AxiMstPortMaxUniqIds-1:0] to_serializer_reqs; | ||
slv_resp_t [AxiMstPortMaxUniqIds-1:0] to_serializer_resps; | ||
|
||
axi_demux #( | ||
.AxiIdWidth ( AxiSlvPortIdWidth ), | ||
.aw_chan_t ( slv_aw_t ), | ||
.w_chan_t ( w_t ), | ||
.b_chan_t ( slv_b_t ), | ||
.ar_chan_t ( slv_ar_t ), | ||
.r_chan_t ( slv_r_t ), | ||
.axi_req_t ( slv_req_t ), | ||
.axi_resp_t ( slv_resp_t ), | ||
.NoMstPorts ( AxiMstPortMaxUniqIds ), | ||
.MaxTrans ( AxiSlvPortMaxTxns ), | ||
.AxiLookBits ( AxiSlvPortIdWidth ), | ||
.AtopSupport ( AtopSupport ), | ||
.SpillAw ( 1'b1 ), | ||
.SpillW ( 1'b0 ), | ||
.SpillB ( 1'b0 ), | ||
.SpillAr ( 1'b1 ), | ||
.SpillR ( 1'b0 ) | ||
) i_axi_demux ( | ||
.clk_i, | ||
.rst_ni, | ||
.test_i ( 1'b0 ), | ||
.slv_req_i ( slv_req_i ), | ||
.slv_aw_select_i ( slv_aw_select ), | ||
.slv_ar_select_i ( slv_ar_select ), | ||
.slv_resp_o ( slv_resp_o ), | ||
.mst_reqs_o ( to_serializer_reqs ), | ||
.mst_resps_i ( to_serializer_resps ) | ||
logic [AxiMstPortMaxUniqIds-1:0] to_serializer_resps_b_valid, to_serializer_resps_r_valid; | ||
|
||
logic no_w_route, no_w_space; | ||
|
||
onehot_to_bin #( | ||
.ONEHOT_WIDTH( AxiMstPortMaxUniqIds ) | ||
) i_slv_b_select ( | ||
.onehot(to_serializer_resps_b_valid), | ||
.bin (slv_b_select) | ||
); | ||
|
||
onehot_to_bin #( | ||
.ONEHOT_WIDTH( AxiMstPortMaxUniqIds ) | ||
) i_slv_r_select ( | ||
.onehot(to_serializer_resps_r_valid), | ||
.bin (slv_r_select) | ||
); | ||
|
||
// Due to static ID mapping, ID consistency checking is not needed. | ||
always_comb begin | ||
// AW, W, AR | ||
for (int unsigned i = 0; i < AxiMstPortMaxUniqIds; i++) begin | ||
to_serializer_reqs[i] = slv_req_i; // .aw, .w, .ar | ||
to_serializer_reqs[i].aw_valid = '0; | ||
to_serializer_reqs[i].w_valid = '0; | ||
to_serializer_reqs[i].ar_valid = '0; | ||
end | ||
to_serializer_reqs[slv_aw_select].aw_valid = slv_req_i.aw_valid; | ||
slv_resp_o.aw_ready = to_serializer_resps[slv_aw_select].aw_ready; | ||
|
||
slv_resp_o.w_ready = mst_resp_i.w_ready; | ||
|
||
to_serializer_reqs[slv_ar_select].ar_valid = slv_req_i.ar_valid; | ||
slv_resp_o.ar_ready = to_serializer_resps[slv_ar_select].ar_ready; | ||
|
||
|
||
// B, R (these are passed through or both gated inside the serializer) | ||
slv_resp_o.b_valid = |to_serializer_resps_b_valid; | ||
slv_resp_o.b = to_serializer_resps[slv_b_select].b; | ||
slv_resp_o.r_valid = |to_serializer_resps_r_valid; | ||
slv_resp_o.r = to_serializer_resps[slv_r_select].r; | ||
for (int unsigned i = 0; i < AxiMstPortMaxUniqIds; i++) begin | ||
to_serializer_resps_b_valid[i] = to_serializer_resps[i].b_valid; | ||
to_serializer_resps_r_valid[i] = to_serializer_resps[i].r_valid; | ||
|
||
to_serializer_reqs[i].b_ready = slv_req_i.b_ready; | ||
to_serializer_reqs[i].r_ready = slv_req_i.r_ready; | ||
end | ||
end | ||
|
||
slv_req_t [AxiMstPortMaxUniqIds-1:0] tmp_serializer_reqs; | ||
slv_resp_t [AxiMstPortMaxUniqIds-1:0] tmp_serializer_resps; | ||
ser_req_t [AxiMstPortMaxUniqIds-1:0] from_serializer_reqs; | ||
ser_resp_t [AxiMstPortMaxUniqIds-1:0] from_serializer_resps; | ||
mst_req_t [AxiMstPortMaxUniqIds-1:0] from_serializer_reqs; | ||
mst_resp_t [AxiMstPortMaxUniqIds-1:0] from_serializer_resps; | ||
|
||
for (genvar i = 0; i < AxiMstPortMaxUniqIds; i++) begin : gen_serializers | ||
// serializer takes care to ensure unique IDs for ATOPs | ||
axi_serializer #( | ||
.MaxReadTxns ( AxiMstPortMaxTxnsPerId ), | ||
.MaxWriteTxns ( AxiMstPortMaxTxnsPerId ), | ||
|
@@ -231,110 +192,71 @@ module axi_id_serialize #( | |
); | ||
always_comb begin | ||
`AXI_SET_REQ_STRUCT(from_serializer_reqs[i], tmp_serializer_reqs[i]) | ||
// Truncate to ID width 1 as all requests have ID '0. | ||
from_serializer_reqs[i].aw.id = tmp_serializer_reqs[i].aw.id[0]; | ||
from_serializer_reqs[i].ar.id = tmp_serializer_reqs[i].ar.id[0]; | ||
from_serializer_reqs[i].aw.id = i; | ||
from_serializer_reqs[i].ar.id = i; | ||
`AXI_SET_RESP_STRUCT(tmp_serializer_resps[i], from_serializer_resps[i]) | ||
// Zero-extend response IDs. | ||
tmp_serializer_resps[i].b.id = {{AxiSlvPortIdWidth-1{1'b0}}, from_serializer_resps[i].b.id}; | ||
tmp_serializer_resps[i].r.id = {{AxiSlvPortIdWidth-1{1'b0}}, from_serializer_resps[i].r.id}; | ||
tmp_serializer_resps[i].b.id = '0; | ||
tmp_serializer_resps[i].r.id = '0; | ||
end | ||
end | ||
|
||
mux_req_t axi_mux_req; | ||
mux_resp_t axi_mux_resp; | ||
|
||
axi_mux #( | ||
.SlvAxiIDWidth ( 32'd1 ), | ||
.slv_aw_chan_t ( ser_aw_t ), | ||
.mst_aw_chan_t ( mux_aw_t ), | ||
.w_chan_t ( w_t ), | ||
.slv_b_chan_t ( ser_b_t ), | ||
.mst_b_chan_t ( mux_b_t ), | ||
.slv_ar_chan_t ( ser_ar_t ), | ||
.mst_ar_chan_t ( mux_ar_t ), | ||
.slv_r_chan_t ( ser_r_t ), | ||
.mst_r_chan_t ( mux_r_t ), | ||
.slv_req_t ( ser_req_t ), | ||
.slv_resp_t ( ser_resp_t ), | ||
.mst_req_t ( mux_req_t ), | ||
.mst_resp_t ( mux_resp_t ), | ||
.NoSlvPorts ( AxiMstPortMaxUniqIds ), | ||
.MaxWTrans ( AxiMstPortMaxTxnsPerId ), | ||
.FallThrough ( 1'b0 ), | ||
.SpillAw ( 1'b1 ), | ||
.SpillW ( 1'b0 ), | ||
.SpillB ( 1'b0 ), | ||
.SpillAr ( 1'b1 ), | ||
.SpillR ( 1'b0 ) | ||
) i_axi_mux ( | ||
.clk_i, | ||
.rst_ni, | ||
.test_i ( 1'b0 ), | ||
.slv_reqs_i ( from_serializer_reqs ), | ||
.slv_resps_o ( from_serializer_resps ), | ||
.mst_req_o ( axi_mux_req ), | ||
.mst_resp_i ( axi_mux_resp ) | ||
logic [AxiMstPortMaxUniqIds-1:0] from_serializer_reqs_aw_valid, | ||
from_serializer_reqs_w_valid, | ||
from_serializer_reqs_ar_valid, | ||
from_serializer_reqs_b_ready, | ||
from_serializer_reqs_r_ready; | ||
|
||
select_t mst_aw_select, mst_w_select, mst_ar_select; | ||
|
||
onehot_to_bin #( | ||
.ONEHOT_WIDTH( AxiMstPortMaxUniqIds ) | ||
) i_mst_aw_select ( | ||
.onehot(from_serializer_reqs_aw_valid), | ||
.bin (mst_aw_select) | ||
); | ||
|
||
// Shift the ID one down if needed, as mux prepends IDs | ||
if (MuxIdWidth > 32'd1) begin : gen_id_shift | ||
always_comb begin | ||
`AXI_SET_REQ_STRUCT(mst_req_o, axi_mux_req) | ||
mst_req_o.aw.id = mst_id_t'(axi_mux_req.aw.id >> 32'd1); | ||
mst_req_o.ar.id = mst_id_t'(axi_mux_req.ar.id >> 32'd1); | ||
`AXI_SET_RESP_STRUCT(axi_mux_resp, mst_resp_i) | ||
axi_mux_resp.b.id = mux_id_t'(mst_resp_i.b.id << 32'd1); | ||
axi_mux_resp.r.id = mux_id_t'(mst_resp_i.r.id << 32'd1); | ||
onehot_to_bin #( | ||
.ONEHOT_WIDTH( AxiMstPortMaxUniqIds ) | ||
) i_mst_w_select ( | ||
.onehot(from_serializer_reqs_w_valid), | ||
.bin (mst_w_select) | ||
); | ||
|
||
onehot_to_bin #( | ||
.ONEHOT_WIDTH( AxiMstPortMaxUniqIds ) | ||
) i_mst_ar_select ( | ||
.onehot(from_serializer_reqs_ar_valid), | ||
.bin (mst_ar_select) | ||
); | ||
|
||
always_comb begin | ||
mst_req_o.aw_valid = |from_serializer_reqs_aw_valid; | ||
mst_req_o.aw = from_serializer_reqs[mst_aw_select].aw; | ||
mst_req_o.w_valid = slv_req_i.w_valid; | ||
mst_req_o.w = slv_req_i.w; | ||
mst_req_o.ar_valid = |from_serializer_reqs_ar_valid; | ||
mst_req_o.ar = from_serializer_reqs[mst_ar_select].ar; | ||
for (int unsigned i = 0; i < AxiMstPortMaxUniqIds; i++) begin | ||
from_serializer_reqs_aw_valid[i] = from_serializer_reqs[i].aw_valid; | ||
from_serializer_reqs_ar_valid[i] = from_serializer_reqs[i].ar_valid; | ||
|
||
from_serializer_resps[i].aw_ready = mst_resp_i.aw_ready; | ||
from_serializer_resps[i].ar_ready = mst_resp_i.ar_ready; | ||
end | ||
end else begin : gen_no_id_shift | ||
axi_id_prepend #( | ||
.NoBus ( 32'd1 ), | ||
.AxiIdWidthSlvPort ( MuxIdWidth ), | ||
.AxiIdWidthMstPort ( AxiMstPortIdWidth ), | ||
.slv_aw_chan_t ( mux_aw_t ), | ||
.slv_w_chan_t ( w_t ), | ||
.slv_b_chan_t ( mux_b_t ), | ||
.slv_ar_chan_t ( mux_ar_t ), | ||
.slv_r_chan_t ( mux_r_t ), | ||
.mst_aw_chan_t ( mst_aw_t ), | ||
.mst_w_chan_t ( w_t ), | ||
.mst_b_chan_t ( mst_b_t ), | ||
.mst_ar_chan_t ( mst_ar_t ), | ||
.mst_r_chan_t ( mst_r_t ) | ||
) i_axi_id_prepend ( | ||
.pre_id_i ( '0 ), | ||
.slv_aw_chans_i ( axi_mux_req.aw ), | ||
.slv_aw_valids_i ( axi_mux_req.aw_valid ), | ||
.slv_aw_readies_o ( axi_mux_resp.aw_ready ), | ||
.slv_w_chans_i ( axi_mux_req.w ), | ||
.slv_w_valids_i ( axi_mux_req.w_valid ), | ||
.slv_w_readies_o ( axi_mux_resp.w_ready ), | ||
.slv_b_chans_o ( axi_mux_resp.b ), | ||
.slv_b_valids_o ( axi_mux_resp.b_valid ), | ||
.slv_b_readies_i ( axi_mux_req.b_ready ), | ||
.slv_ar_chans_i ( axi_mux_req.ar ), | ||
.slv_ar_valids_i ( axi_mux_req.ar_valid ), | ||
.slv_ar_readies_o ( axi_mux_resp.ar_ready ), | ||
.slv_r_chans_o ( axi_mux_resp.r ), | ||
.slv_r_valids_o ( axi_mux_resp.r_valid ), | ||
.slv_r_readies_i ( axi_mux_req.r_ready ), | ||
.mst_aw_chans_o ( mst_req_o.aw ), | ||
.mst_aw_valids_o ( mst_req_o.aw_valid ), | ||
.mst_aw_readies_i ( mst_resp_i.aw_ready ), | ||
.mst_w_chans_o ( mst_req_o.w ), | ||
.mst_w_valids_o ( mst_req_o.w_valid ), | ||
.mst_w_readies_i ( mst_resp_i.w_ready ), | ||
.mst_b_chans_i ( mst_resp_i.b ), | ||
.mst_b_valids_i ( mst_resp_i.b_valid ), | ||
.mst_b_readies_o ( mst_req_o.b_ready ), | ||
.mst_ar_chans_o ( mst_req_o.ar ), | ||
.mst_ar_valids_o ( mst_req_o.ar_valid ), | ||
.mst_ar_readies_i ( mst_resp_i.ar_ready ), | ||
.mst_r_chans_i ( mst_resp_i.r ), | ||
.mst_r_valids_i ( mst_resp_i.r_valid ), | ||
.mst_r_readies_o ( mst_req_o.r_ready ) | ||
); | ||
|
||
for (int unsigned i = 0; i < AxiMstPortMaxUniqIds; i++) begin | ||
from_serializer_reqs_b_ready[i] = from_serializer_reqs[i].b_ready; | ||
from_serializer_reqs_r_ready[i] = from_serializer_reqs[i].r_ready; | ||
from_serializer_resps[i].b_valid = '0; | ||
from_serializer_resps[i].r_valid = '0; | ||
from_serializer_resps[i].b = mst_resp_i.b; | ||
from_serializer_resps[i].r = mst_resp_i.r; | ||
end | ||
from_serializer_resps[mst_resp_i.b.id].b_valid = mst_resp_i.b_valid; | ||
mst_req_o.b_ready = |from_serializer_reqs_b_ready; | ||
from_serializer_resps[mst_resp_i.r.id].r_valid = mst_resp_i.r_valid; | ||
mst_req_o.r_ready = |from_serializer_reqs_r_ready; | ||
end | ||
|
||
// pragma translate_off | ||
|