mirror of
https://github.com/corundum/corundum.git
synced 2025-01-30 08:32:52 +08:00
merged changes in eth
This commit is contained in:
commit
bbc94af35e
@ -598,7 +598,7 @@ axis_switch #(
|
|||||||
.DATA_WIDTH(64),
|
.DATA_WIDTH(64),
|
||||||
.KEEP_WIDTH(8),
|
.KEEP_WIDTH(8),
|
||||||
.ID_ENABLE(0),
|
.ID_ENABLE(0),
|
||||||
.DEST_WIDTH(2),
|
.S_DEST_WIDTH(2),
|
||||||
.USER_ENABLE(1),
|
.USER_ENABLE(1),
|
||||||
.USER_WIDTH(1),
|
.USER_WIDTH(1),
|
||||||
.M_BASE({2'd2, 2'd1, 2'd0}),
|
.M_BASE({2'd2, 2'd1, 2'd0}),
|
||||||
|
@ -639,7 +639,7 @@ axis_switch #(
|
|||||||
.DATA_WIDTH(64),
|
.DATA_WIDTH(64),
|
||||||
.KEEP_WIDTH(8),
|
.KEEP_WIDTH(8),
|
||||||
.ID_ENABLE(0),
|
.ID_ENABLE(0),
|
||||||
.DEST_WIDTH(2),
|
.S_DEST_WIDTH(2),
|
||||||
.USER_ENABLE(1),
|
.USER_ENABLE(1),
|
||||||
.USER_WIDTH(1),
|
.USER_WIDTH(1),
|
||||||
.M_BASE({2'd2, 2'd1, 2'd0}),
|
.M_BASE({2'd2, 2'd1, 2'd0}),
|
||||||
|
@ -639,7 +639,7 @@ axis_switch #(
|
|||||||
.DATA_WIDTH(64),
|
.DATA_WIDTH(64),
|
||||||
.KEEP_WIDTH(8),
|
.KEEP_WIDTH(8),
|
||||||
.ID_ENABLE(0),
|
.ID_ENABLE(0),
|
||||||
.DEST_WIDTH(2),
|
.S_DEST_WIDTH(2),
|
||||||
.USER_ENABLE(1),
|
.USER_ENABLE(1),
|
||||||
.USER_WIDTH(1),
|
.USER_WIDTH(1),
|
||||||
.M_BASE({2'd2, 2'd1, 2'd0}),
|
.M_BASE({2'd2, 2'd1, 2'd0}),
|
||||||
|
@ -43,8 +43,10 @@ module axis_arb_mux #
|
|||||||
parameter KEEP_WIDTH = (DATA_WIDTH/8),
|
parameter KEEP_WIDTH = (DATA_WIDTH/8),
|
||||||
// Propagate tid signal
|
// Propagate tid signal
|
||||||
parameter ID_ENABLE = 0,
|
parameter ID_ENABLE = 0,
|
||||||
// tid signal width
|
// input tid signal width
|
||||||
parameter ID_WIDTH = 8,
|
parameter S_ID_WIDTH = 8,
|
||||||
|
// output tid signal width
|
||||||
|
parameter M_ID_WIDTH = S_ID_WIDTH+$clog2(S_COUNT),
|
||||||
// Propagate tdest signal
|
// Propagate tdest signal
|
||||||
parameter DEST_ENABLE = 0,
|
parameter DEST_ENABLE = 0,
|
||||||
// tdest signal width
|
// tdest signal width
|
||||||
@ -55,6 +57,8 @@ module axis_arb_mux #
|
|||||||
parameter USER_WIDTH = 1,
|
parameter USER_WIDTH = 1,
|
||||||
// Propagate tlast signal
|
// Propagate tlast signal
|
||||||
parameter LAST_ENABLE = 1,
|
parameter LAST_ENABLE = 1,
|
||||||
|
// Update tid with routing information
|
||||||
|
parameter UPDATE_TID = 0,
|
||||||
// select round robin arbitration
|
// select round robin arbitration
|
||||||
parameter ARB_TYPE_ROUND_ROBIN = 0,
|
parameter ARB_TYPE_ROUND_ROBIN = 0,
|
||||||
// LSB priority selection
|
// LSB priority selection
|
||||||
@ -67,30 +71,47 @@ module axis_arb_mux #
|
|||||||
/*
|
/*
|
||||||
* AXI Stream inputs
|
* AXI Stream inputs
|
||||||
*/
|
*/
|
||||||
input wire [S_COUNT*DATA_WIDTH-1:0] s_axis_tdata,
|
input wire [S_COUNT*DATA_WIDTH-1:0] s_axis_tdata,
|
||||||
input wire [S_COUNT*KEEP_WIDTH-1:0] s_axis_tkeep,
|
input wire [S_COUNT*KEEP_WIDTH-1:0] s_axis_tkeep,
|
||||||
input wire [S_COUNT-1:0] s_axis_tvalid,
|
input wire [S_COUNT-1:0] s_axis_tvalid,
|
||||||
output wire [S_COUNT-1:0] s_axis_tready,
|
output wire [S_COUNT-1:0] s_axis_tready,
|
||||||
input wire [S_COUNT-1:0] s_axis_tlast,
|
input wire [S_COUNT-1:0] s_axis_tlast,
|
||||||
input wire [S_COUNT*ID_WIDTH-1:0] s_axis_tid,
|
input wire [S_COUNT*S_ID_WIDTH-1:0] s_axis_tid,
|
||||||
input wire [S_COUNT*DEST_WIDTH-1:0] s_axis_tdest,
|
input wire [S_COUNT*DEST_WIDTH-1:0] s_axis_tdest,
|
||||||
input wire [S_COUNT*USER_WIDTH-1:0] s_axis_tuser,
|
input wire [S_COUNT*USER_WIDTH-1:0] s_axis_tuser,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AXI Stream output
|
* AXI Stream output
|
||||||
*/
|
*/
|
||||||
output wire [DATA_WIDTH-1:0] m_axis_tdata,
|
output wire [DATA_WIDTH-1:0] m_axis_tdata,
|
||||||
output wire [KEEP_WIDTH-1:0] m_axis_tkeep,
|
output wire [KEEP_WIDTH-1:0] m_axis_tkeep,
|
||||||
output wire m_axis_tvalid,
|
output wire m_axis_tvalid,
|
||||||
input wire m_axis_tready,
|
input wire m_axis_tready,
|
||||||
output wire m_axis_tlast,
|
output wire m_axis_tlast,
|
||||||
output wire [ID_WIDTH-1:0] m_axis_tid,
|
output wire [M_ID_WIDTH-1:0] m_axis_tid,
|
||||||
output wire [DEST_WIDTH-1:0] m_axis_tdest,
|
output wire [DEST_WIDTH-1:0] m_axis_tdest,
|
||||||
output wire [USER_WIDTH-1:0] m_axis_tuser
|
output wire [USER_WIDTH-1:0] m_axis_tuser
|
||||||
);
|
);
|
||||||
|
|
||||||
parameter CL_S_COUNT = $clog2(S_COUNT);
|
parameter CL_S_COUNT = $clog2(S_COUNT);
|
||||||
|
|
||||||
|
parameter S_ID_WIDTH_INT = S_ID_WIDTH > 0 ? S_ID_WIDTH : 1;
|
||||||
|
|
||||||
|
// check configuration
|
||||||
|
initial begin
|
||||||
|
if (UPDATE_TID) begin
|
||||||
|
if (!ID_ENABLE) begin
|
||||||
|
$error("Error: UPDATE_TID set requires ID_ENABLE set (instance %m)");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (M_ID_WIDTH < CL_S_COUNT) begin
|
||||||
|
$error("Error: M_ID_WIDTH too small for port count (instance %m)");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
wire [S_COUNT-1:0] request;
|
wire [S_COUNT-1:0] request;
|
||||||
wire [S_COUNT-1:0] acknowledge;
|
wire [S_COUNT-1:0] acknowledge;
|
||||||
wire [S_COUNT-1:0] grant;
|
wire [S_COUNT-1:0] grant;
|
||||||
@ -103,7 +124,7 @@ reg [KEEP_WIDTH-1:0] m_axis_tkeep_int;
|
|||||||
reg m_axis_tvalid_int;
|
reg m_axis_tvalid_int;
|
||||||
reg m_axis_tready_int_reg = 1'b0;
|
reg m_axis_tready_int_reg = 1'b0;
|
||||||
reg m_axis_tlast_int;
|
reg m_axis_tlast_int;
|
||||||
reg [ID_WIDTH-1:0] m_axis_tid_int;
|
reg [M_ID_WIDTH-1:0] m_axis_tid_int;
|
||||||
reg [DEST_WIDTH-1:0] m_axis_tdest_int;
|
reg [DEST_WIDTH-1:0] m_axis_tdest_int;
|
||||||
reg [USER_WIDTH-1:0] m_axis_tuser_int;
|
reg [USER_WIDTH-1:0] m_axis_tuser_int;
|
||||||
wire m_axis_tready_int_early;
|
wire m_axis_tready_int_early;
|
||||||
@ -116,7 +137,7 @@ wire [KEEP_WIDTH-1:0] current_s_tkeep = s_axis_tkeep[grant_encoded*KEEP_WIDTH +
|
|||||||
wire current_s_tvalid = s_axis_tvalid[grant_encoded];
|
wire current_s_tvalid = s_axis_tvalid[grant_encoded];
|
||||||
wire current_s_tready = s_axis_tready[grant_encoded];
|
wire current_s_tready = s_axis_tready[grant_encoded];
|
||||||
wire current_s_tlast = s_axis_tlast[grant_encoded];
|
wire current_s_tlast = s_axis_tlast[grant_encoded];
|
||||||
wire [ID_WIDTH-1:0] current_s_tid = s_axis_tid[grant_encoded*ID_WIDTH +: ID_WIDTH];
|
wire [S_ID_WIDTH-1:0] current_s_tid = s_axis_tid[grant_encoded*S_ID_WIDTH +: S_ID_WIDTH_INT];
|
||||||
wire [DEST_WIDTH-1:0] current_s_tdest = s_axis_tdest[grant_encoded*DEST_WIDTH +: DEST_WIDTH];
|
wire [DEST_WIDTH-1:0] current_s_tdest = s_axis_tdest[grant_encoded*DEST_WIDTH +: DEST_WIDTH];
|
||||||
wire [USER_WIDTH-1:0] current_s_tuser = s_axis_tuser[grant_encoded*USER_WIDTH +: USER_WIDTH];
|
wire [USER_WIDTH-1:0] current_s_tuser = s_axis_tuser[grant_encoded*USER_WIDTH +: USER_WIDTH];
|
||||||
|
|
||||||
@ -148,6 +169,9 @@ always @* begin
|
|||||||
m_axis_tvalid_int = current_s_tvalid && m_axis_tready_int_reg && grant_valid;
|
m_axis_tvalid_int = current_s_tvalid && m_axis_tready_int_reg && grant_valid;
|
||||||
m_axis_tlast_int = current_s_tlast;
|
m_axis_tlast_int = current_s_tlast;
|
||||||
m_axis_tid_int = current_s_tid;
|
m_axis_tid_int = current_s_tid;
|
||||||
|
if (UPDATE_TID && S_COUNT > 1) begin
|
||||||
|
m_axis_tid_int[M_ID_WIDTH-1:M_ID_WIDTH-CL_S_COUNT] = grant_encoded;
|
||||||
|
end
|
||||||
m_axis_tdest_int = current_s_tdest;
|
m_axis_tdest_int = current_s_tdest;
|
||||||
m_axis_tuser_int = current_s_tuser;
|
m_axis_tuser_int = current_s_tuser;
|
||||||
end
|
end
|
||||||
@ -157,7 +181,7 @@ reg [DATA_WIDTH-1:0] m_axis_tdata_reg = {DATA_WIDTH{1'b0}};
|
|||||||
reg [KEEP_WIDTH-1:0] m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}};
|
reg [KEEP_WIDTH-1:0] m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}};
|
||||||
reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next;
|
reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next;
|
||||||
reg m_axis_tlast_reg = 1'b0;
|
reg m_axis_tlast_reg = 1'b0;
|
||||||
reg [ID_WIDTH-1:0] m_axis_tid_reg = {ID_WIDTH{1'b0}};
|
reg [M_ID_WIDTH-1:0] m_axis_tid_reg = {M_ID_WIDTH{1'b0}};
|
||||||
reg [DEST_WIDTH-1:0] m_axis_tdest_reg = {DEST_WIDTH{1'b0}};
|
reg [DEST_WIDTH-1:0] m_axis_tdest_reg = {DEST_WIDTH{1'b0}};
|
||||||
reg [USER_WIDTH-1:0] m_axis_tuser_reg = {USER_WIDTH{1'b0}};
|
reg [USER_WIDTH-1:0] m_axis_tuser_reg = {USER_WIDTH{1'b0}};
|
||||||
|
|
||||||
@ -165,7 +189,7 @@ reg [DATA_WIDTH-1:0] temp_m_axis_tdata_reg = {DATA_WIDTH{1'b0}};
|
|||||||
reg [KEEP_WIDTH-1:0] temp_m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}};
|
reg [KEEP_WIDTH-1:0] temp_m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}};
|
||||||
reg temp_m_axis_tvalid_reg = 1'b0, temp_m_axis_tvalid_next;
|
reg temp_m_axis_tvalid_reg = 1'b0, temp_m_axis_tvalid_next;
|
||||||
reg temp_m_axis_tlast_reg = 1'b0;
|
reg temp_m_axis_tlast_reg = 1'b0;
|
||||||
reg [ID_WIDTH-1:0] temp_m_axis_tid_reg = {ID_WIDTH{1'b0}};
|
reg [M_ID_WIDTH-1:0] temp_m_axis_tid_reg = {M_ID_WIDTH{1'b0}};
|
||||||
reg [DEST_WIDTH-1:0] temp_m_axis_tdest_reg = {DEST_WIDTH{1'b0}};
|
reg [DEST_WIDTH-1:0] temp_m_axis_tdest_reg = {DEST_WIDTH{1'b0}};
|
||||||
reg [USER_WIDTH-1:0] temp_m_axis_tuser_reg = {USER_WIDTH{1'b0}};
|
reg [USER_WIDTH-1:0] temp_m_axis_tuser_reg = {USER_WIDTH{1'b0}};
|
||||||
|
|
||||||
@ -178,7 +202,7 @@ assign m_axis_tdata = m_axis_tdata_reg;
|
|||||||
assign m_axis_tkeep = KEEP_ENABLE ? m_axis_tkeep_reg : {KEEP_WIDTH{1'b1}};
|
assign m_axis_tkeep = KEEP_ENABLE ? m_axis_tkeep_reg : {KEEP_WIDTH{1'b1}};
|
||||||
assign m_axis_tvalid = m_axis_tvalid_reg;
|
assign m_axis_tvalid = m_axis_tvalid_reg;
|
||||||
assign m_axis_tlast = LAST_ENABLE ? m_axis_tlast_reg : 1'b1;
|
assign m_axis_tlast = LAST_ENABLE ? m_axis_tlast_reg : 1'b1;
|
||||||
assign m_axis_tid = ID_ENABLE ? m_axis_tid_reg : {ID_WIDTH{1'b0}};
|
assign m_axis_tid = ID_ENABLE ? m_axis_tid_reg : {M_ID_WIDTH{1'b0}};
|
||||||
assign m_axis_tdest = DEST_ENABLE ? m_axis_tdest_reg : {DEST_WIDTH{1'b0}};
|
assign m_axis_tdest = DEST_ENABLE ? m_axis_tdest_reg : {DEST_WIDTH{1'b0}};
|
||||||
assign m_axis_tuser = USER_ENABLE ? m_axis_tuser_reg : {USER_WIDTH{1'b0}};
|
assign m_axis_tuser = USER_ENABLE ? m_axis_tuser_reg : {USER_WIDTH{1'b0}};
|
||||||
|
|
||||||
|
@ -78,8 +78,10 @@ module {{name}} #
|
|||||||
parameter KEEP_WIDTH = (DATA_WIDTH/8),
|
parameter KEEP_WIDTH = (DATA_WIDTH/8),
|
||||||
// Propagate tid signal
|
// Propagate tid signal
|
||||||
parameter ID_ENABLE = 0,
|
parameter ID_ENABLE = 0,
|
||||||
// tid signal width
|
// input tid signal width
|
||||||
parameter ID_WIDTH = 8,
|
parameter S_ID_WIDTH = 8,
|
||||||
|
// output tid signal width
|
||||||
|
parameter M_ID_WIDTH = S_ID_WIDTH+{{cn}},
|
||||||
// Propagate tdest signal
|
// Propagate tdest signal
|
||||||
parameter DEST_ENABLE = 0,
|
parameter DEST_ENABLE = 0,
|
||||||
// tdest signal width
|
// tdest signal width
|
||||||
@ -90,39 +92,41 @@ module {{name}} #
|
|||||||
parameter USER_WIDTH = 1,
|
parameter USER_WIDTH = 1,
|
||||||
// Propagate tlast signal
|
// Propagate tlast signal
|
||||||
parameter LAST_ENABLE = 1,
|
parameter LAST_ENABLE = 1,
|
||||||
|
// Update tid with routing information
|
||||||
|
parameter UPDATE_TID = 0,
|
||||||
// select round robin arbitration
|
// select round robin arbitration
|
||||||
parameter ARB_TYPE_ROUND_ROBIN = 0,
|
parameter ARB_TYPE_ROUND_ROBIN = 0,
|
||||||
// LSB priority selection
|
// LSB priority selection
|
||||||
parameter ARB_LSB_HIGH_PRIORITY = 1
|
parameter ARB_LSB_HIGH_PRIORITY = 1
|
||||||
)
|
)
|
||||||
(
|
(
|
||||||
input wire clk,
|
input wire clk,
|
||||||
input wire rst,
|
input wire rst,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AXI Stream inputs
|
* AXI Stream inputs
|
||||||
*/
|
*/
|
||||||
{%- for p in range(n) %}
|
{%- for p in range(n) %}
|
||||||
input wire [DATA_WIDTH-1:0] s{{'%02d'%p}}_axis_tdata,
|
input wire [DATA_WIDTH-1:0] s{{'%02d'%p}}_axis_tdata,
|
||||||
input wire [KEEP_WIDTH-1:0] s{{'%02d'%p}}_axis_tkeep,
|
input wire [KEEP_WIDTH-1:0] s{{'%02d'%p}}_axis_tkeep,
|
||||||
input wire s{{'%02d'%p}}_axis_tvalid,
|
input wire s{{'%02d'%p}}_axis_tvalid,
|
||||||
output wire s{{'%02d'%p}}_axis_tready,
|
output wire s{{'%02d'%p}}_axis_tready,
|
||||||
input wire s{{'%02d'%p}}_axis_tlast,
|
input wire s{{'%02d'%p}}_axis_tlast,
|
||||||
input wire [ID_WIDTH-1:0] s{{'%02d'%p}}_axis_tid,
|
input wire [S_ID_WIDTH-1:0] s{{'%02d'%p}}_axis_tid,
|
||||||
input wire [DEST_WIDTH-1:0] s{{'%02d'%p}}_axis_tdest,
|
input wire [DEST_WIDTH-1:0] s{{'%02d'%p}}_axis_tdest,
|
||||||
input wire [USER_WIDTH-1:0] s{{'%02d'%p}}_axis_tuser,
|
input wire [USER_WIDTH-1:0] s{{'%02d'%p}}_axis_tuser,
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
/*
|
/*
|
||||||
* AXI Stream output
|
* AXI Stream output
|
||||||
*/
|
*/
|
||||||
output wire [DATA_WIDTH-1:0] m_axis_tdata,
|
output wire [DATA_WIDTH-1:0] m_axis_tdata,
|
||||||
output wire [KEEP_WIDTH-1:0] m_axis_tkeep,
|
output wire [KEEP_WIDTH-1:0] m_axis_tkeep,
|
||||||
output wire m_axis_tvalid,
|
output wire m_axis_tvalid,
|
||||||
input wire m_axis_tready,
|
input wire m_axis_tready,
|
||||||
output wire m_axis_tlast,
|
output wire m_axis_tlast,
|
||||||
output wire [ID_WIDTH-1:0] m_axis_tid,
|
output wire [M_ID_WIDTH-1:0] m_axis_tid,
|
||||||
output wire [DEST_WIDTH-1:0] m_axis_tdest,
|
output wire [DEST_WIDTH-1:0] m_axis_tdest,
|
||||||
output wire [USER_WIDTH-1:0] m_axis_tuser
|
output wire [USER_WIDTH-1:0] m_axis_tuser
|
||||||
);
|
);
|
||||||
|
|
||||||
axis_arb_mux #(
|
axis_arb_mux #(
|
||||||
@ -131,12 +135,14 @@ axis_arb_mux #(
|
|||||||
.KEEP_ENABLE(KEEP_ENABLE),
|
.KEEP_ENABLE(KEEP_ENABLE),
|
||||||
.KEEP_WIDTH(KEEP_WIDTH),
|
.KEEP_WIDTH(KEEP_WIDTH),
|
||||||
.ID_ENABLE(ID_ENABLE),
|
.ID_ENABLE(ID_ENABLE),
|
||||||
.ID_WIDTH(ID_WIDTH),
|
.S_ID_WIDTH(S_ID_WIDTH),
|
||||||
|
.M_ID_WIDTH(M_ID_WIDTH),
|
||||||
.DEST_ENABLE(DEST_ENABLE),
|
.DEST_ENABLE(DEST_ENABLE),
|
||||||
.DEST_WIDTH(DEST_WIDTH),
|
.DEST_WIDTH(DEST_WIDTH),
|
||||||
.USER_ENABLE(USER_ENABLE),
|
.USER_ENABLE(USER_ENABLE),
|
||||||
.USER_WIDTH(USER_WIDTH),
|
.USER_WIDTH(USER_WIDTH),
|
||||||
.LAST_ENABLE(LAST_ENABLE),
|
.LAST_ENABLE(LAST_ENABLE),
|
||||||
|
.UPDATE_TID(UPDATE_TID),
|
||||||
.ARB_TYPE_ROUND_ROBIN(ARB_TYPE_ROUND_ROBIN),
|
.ARB_TYPE_ROUND_ROBIN(ARB_TYPE_ROUND_ROBIN),
|
||||||
.ARB_LSB_HIGH_PRIORITY(ARB_LSB_HIGH_PRIORITY)
|
.ARB_LSB_HIGH_PRIORITY(ARB_LSB_HIGH_PRIORITY)
|
||||||
)
|
)
|
||||||
|
@ -47,51 +47,72 @@ module axis_demux #
|
|||||||
parameter ID_WIDTH = 8,
|
parameter ID_WIDTH = 8,
|
||||||
// Propagate tdest signal
|
// Propagate tdest signal
|
||||||
parameter DEST_ENABLE = 0,
|
parameter DEST_ENABLE = 0,
|
||||||
// tdest signal width
|
// output tdest signal width
|
||||||
parameter DEST_WIDTH = 8,
|
parameter M_DEST_WIDTH = 8,
|
||||||
|
// input tdest signal width
|
||||||
|
parameter S_DEST_WIDTH = M_DEST_WIDTH+$clog2(M_COUNT),
|
||||||
// Propagate tuser signal
|
// Propagate tuser signal
|
||||||
parameter USER_ENABLE = 1,
|
parameter USER_ENABLE = 1,
|
||||||
// tuser signal width
|
// tuser signal width
|
||||||
parameter USER_WIDTH = 1
|
parameter USER_WIDTH = 1,
|
||||||
|
// route via tdest
|
||||||
|
parameter TDEST_ROUTE = 0
|
||||||
)
|
)
|
||||||
(
|
(
|
||||||
input wire clk,
|
input wire clk,
|
||||||
input wire rst,
|
input wire rst,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AXI input
|
* AXI input
|
||||||
*/
|
*/
|
||||||
input wire [DATA_WIDTH-1:0] s_axis_tdata,
|
input wire [DATA_WIDTH-1:0] s_axis_tdata,
|
||||||
input wire [KEEP_WIDTH-1:0] s_axis_tkeep,
|
input wire [KEEP_WIDTH-1:0] s_axis_tkeep,
|
||||||
input wire s_axis_tvalid,
|
input wire s_axis_tvalid,
|
||||||
output wire s_axis_tready,
|
output wire s_axis_tready,
|
||||||
input wire s_axis_tlast,
|
input wire s_axis_tlast,
|
||||||
input wire [ID_WIDTH-1:0] s_axis_tid,
|
input wire [ID_WIDTH-1:0] s_axis_tid,
|
||||||
input wire [DEST_WIDTH-1:0] s_axis_tdest,
|
input wire [S_DEST_WIDTH-1:0] s_axis_tdest,
|
||||||
input wire [USER_WIDTH-1:0] s_axis_tuser,
|
input wire [USER_WIDTH-1:0] s_axis_tuser,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AXI outputs
|
* AXI outputs
|
||||||
*/
|
*/
|
||||||
output wire [M_COUNT*DATA_WIDTH-1:0] m_axis_tdata,
|
output wire [M_COUNT*DATA_WIDTH-1:0] m_axis_tdata,
|
||||||
output wire [M_COUNT*KEEP_WIDTH-1:0] m_axis_tkeep,
|
output wire [M_COUNT*KEEP_WIDTH-1:0] m_axis_tkeep,
|
||||||
output wire [M_COUNT-1:0] m_axis_tvalid,
|
output wire [M_COUNT-1:0] m_axis_tvalid,
|
||||||
input wire [M_COUNT-1:0] m_axis_tready,
|
input wire [M_COUNT-1:0] m_axis_tready,
|
||||||
output wire [M_COUNT-1:0] m_axis_tlast,
|
output wire [M_COUNT-1:0] m_axis_tlast,
|
||||||
output wire [M_COUNT*ID_WIDTH-1:0] m_axis_tid,
|
output wire [M_COUNT*ID_WIDTH-1:0] m_axis_tid,
|
||||||
output wire [M_COUNT*DEST_WIDTH-1:0] m_axis_tdest,
|
output wire [M_COUNT*M_DEST_WIDTH-1:0] m_axis_tdest,
|
||||||
output wire [M_COUNT*USER_WIDTH-1:0] m_axis_tuser,
|
output wire [M_COUNT*USER_WIDTH-1:0] m_axis_tuser,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Control
|
* Control
|
||||||
*/
|
*/
|
||||||
input wire enable,
|
input wire enable,
|
||||||
input wire drop,
|
input wire drop,
|
||||||
input wire [$clog2(M_COUNT)-1:0] select
|
input wire [$clog2(M_COUNT)-1:0] select
|
||||||
);
|
);
|
||||||
|
|
||||||
parameter CL_M_COUNT = $clog2(M_COUNT);
|
parameter CL_M_COUNT = $clog2(M_COUNT);
|
||||||
|
|
||||||
|
parameter M_DEST_WIDTH_INT = M_DEST_WIDTH > 0 ? M_DEST_WIDTH : 1;
|
||||||
|
|
||||||
|
// check configuration
|
||||||
|
initial begin
|
||||||
|
if (TDEST_ROUTE) begin
|
||||||
|
if (!DEST_ENABLE) begin
|
||||||
|
$error("Error: TDEST_ROUTE set requires DEST_ENABLE set (instance %m)");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (S_DEST_WIDTH < CL_M_COUNT) begin
|
||||||
|
$error("Error: S_DEST_WIDTH too small for port count (instance %m)");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
reg [CL_M_COUNT-1:0] select_reg = {CL_M_COUNT{1'b0}}, select_ctl, select_next;
|
reg [CL_M_COUNT-1:0] select_reg = {CL_M_COUNT{1'b0}}, select_ctl, select_next;
|
||||||
reg drop_reg = 1'b0, drop_ctl, drop_next;
|
reg drop_reg = 1'b0, drop_ctl, drop_next;
|
||||||
reg frame_reg = 1'b0, frame_ctl, frame_next;
|
reg frame_reg = 1'b0, frame_ctl, frame_next;
|
||||||
@ -99,15 +120,15 @@ reg frame_reg = 1'b0, frame_ctl, frame_next;
|
|||||||
reg s_axis_tready_reg = 1'b0, s_axis_tready_next;
|
reg s_axis_tready_reg = 1'b0, s_axis_tready_next;
|
||||||
|
|
||||||
// internal datapath
|
// internal datapath
|
||||||
reg [DATA_WIDTH-1:0] m_axis_tdata_int;
|
reg [DATA_WIDTH-1:0] m_axis_tdata_int;
|
||||||
reg [KEEP_WIDTH-1:0] m_axis_tkeep_int;
|
reg [KEEP_WIDTH-1:0] m_axis_tkeep_int;
|
||||||
reg [M_COUNT-1:0] m_axis_tvalid_int;
|
reg [M_COUNT-1:0] m_axis_tvalid_int;
|
||||||
reg m_axis_tready_int_reg = 1'b0;
|
reg m_axis_tready_int_reg = 1'b0;
|
||||||
reg m_axis_tlast_int;
|
reg m_axis_tlast_int;
|
||||||
reg [ID_WIDTH-1:0] m_axis_tid_int;
|
reg [ID_WIDTH-1:0] m_axis_tid_int;
|
||||||
reg [DEST_WIDTH-1:0] m_axis_tdest_int;
|
reg [M_DEST_WIDTH-1:0] m_axis_tdest_int;
|
||||||
reg [USER_WIDTH-1:0] m_axis_tuser_int;
|
reg [USER_WIDTH-1:0] m_axis_tuser_int;
|
||||||
wire m_axis_tready_int_early;
|
wire m_axis_tready_int_early;
|
||||||
|
|
||||||
assign s_axis_tready = s_axis_tready_reg && enable;
|
assign s_axis_tready = s_axis_tready_reg && enable;
|
||||||
|
|
||||||
@ -131,8 +152,18 @@ always @* begin
|
|||||||
|
|
||||||
if (!frame_reg && s_axis_tvalid && s_axis_tready) begin
|
if (!frame_reg && s_axis_tvalid && s_axis_tready) begin
|
||||||
// start of frame, grab select value
|
// start of frame, grab select value
|
||||||
select_ctl = select;
|
if (TDEST_ROUTE) begin
|
||||||
drop_ctl = drop;
|
if (M_COUNT > 1) begin
|
||||||
|
select_ctl = s_axis_tdest[S_DEST_WIDTH-1:S_DEST_WIDTH-CL_M_COUNT];
|
||||||
|
drop_ctl = s_axis_tdest[S_DEST_WIDTH-1:S_DEST_WIDTH-CL_M_COUNT] >= M_COUNT;
|
||||||
|
end else begin
|
||||||
|
select_ctl = 0;
|
||||||
|
drop_ctl = 1'b0;
|
||||||
|
end
|
||||||
|
end else begin
|
||||||
|
select_ctl = select;
|
||||||
|
drop_ctl = drop || select >= M_COUNT;
|
||||||
|
end
|
||||||
frame_ctl = 1'b1;
|
frame_ctl = 1'b1;
|
||||||
if (!(s_axis_tready && s_axis_tvalid && s_axis_tlast)) begin
|
if (!(s_axis_tready && s_axis_tvalid && s_axis_tlast)) begin
|
||||||
select_next = select_ctl;
|
select_next = select_ctl;
|
||||||
@ -167,21 +198,21 @@ always @(posedge clk) begin
|
|||||||
end
|
end
|
||||||
|
|
||||||
// output datapath logic
|
// output datapath logic
|
||||||
reg [DATA_WIDTH-1:0] m_axis_tdata_reg = {DATA_WIDTH{1'b0}};
|
reg [DATA_WIDTH-1:0] m_axis_tdata_reg = {DATA_WIDTH{1'b0}};
|
||||||
reg [KEEP_WIDTH-1:0] m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}};
|
reg [KEEP_WIDTH-1:0] m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}};
|
||||||
reg [M_COUNT-1:0] m_axis_tvalid_reg = {M_COUNT{1'b0}}, m_axis_tvalid_next;
|
reg [M_COUNT-1:0] m_axis_tvalid_reg = {M_COUNT{1'b0}}, m_axis_tvalid_next;
|
||||||
reg m_axis_tlast_reg = 1'b0;
|
reg m_axis_tlast_reg = 1'b0;
|
||||||
reg [ID_WIDTH-1:0] m_axis_tid_reg = {ID_WIDTH{1'b0}};
|
reg [ID_WIDTH-1:0] m_axis_tid_reg = {ID_WIDTH{1'b0}};
|
||||||
reg [DEST_WIDTH-1:0] m_axis_tdest_reg = {DEST_WIDTH{1'b0}};
|
reg [M_DEST_WIDTH-1:0] m_axis_tdest_reg = {M_DEST_WIDTH_INT{1'b0}};
|
||||||
reg [USER_WIDTH-1:0] m_axis_tuser_reg = {USER_WIDTH{1'b0}};
|
reg [USER_WIDTH-1:0] m_axis_tuser_reg = {USER_WIDTH{1'b0}};
|
||||||
|
|
||||||
reg [DATA_WIDTH-1:0] temp_m_axis_tdata_reg = {DATA_WIDTH{1'b0}};
|
reg [DATA_WIDTH-1:0] temp_m_axis_tdata_reg = {DATA_WIDTH{1'b0}};
|
||||||
reg [KEEP_WIDTH-1:0] temp_m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}};
|
reg [KEEP_WIDTH-1:0] temp_m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}};
|
||||||
reg [M_COUNT-1:0] temp_m_axis_tvalid_reg = {M_COUNT{1'b0}}, temp_m_axis_tvalid_next;
|
reg [M_COUNT-1:0] temp_m_axis_tvalid_reg = {M_COUNT{1'b0}}, temp_m_axis_tvalid_next;
|
||||||
reg temp_m_axis_tlast_reg = 1'b0;
|
reg temp_m_axis_tlast_reg = 1'b0;
|
||||||
reg [ID_WIDTH-1:0] temp_m_axis_tid_reg = {ID_WIDTH{1'b0}};
|
reg [ID_WIDTH-1:0] temp_m_axis_tid_reg = {ID_WIDTH{1'b0}};
|
||||||
reg [DEST_WIDTH-1:0] temp_m_axis_tdest_reg = {DEST_WIDTH{1'b0}};
|
reg [M_DEST_WIDTH-1:0] temp_m_axis_tdest_reg = {M_DEST_WIDTH_INT{1'b0}};
|
||||||
reg [USER_WIDTH-1:0] temp_m_axis_tuser_reg = {USER_WIDTH{1'b0}};
|
reg [USER_WIDTH-1:0] temp_m_axis_tuser_reg = {USER_WIDTH{1'b0}};
|
||||||
|
|
||||||
// datapath control
|
// datapath control
|
||||||
reg store_axis_int_to_output;
|
reg store_axis_int_to_output;
|
||||||
@ -193,7 +224,7 @@ assign m_axis_tkeep = KEEP_ENABLE ? {M_COUNT{m_axis_tkeep_reg}} : {M_COUNT*KEEP
|
|||||||
assign m_axis_tvalid = m_axis_tvalid_reg;
|
assign m_axis_tvalid = m_axis_tvalid_reg;
|
||||||
assign m_axis_tlast = {M_COUNT{m_axis_tlast_reg}};
|
assign m_axis_tlast = {M_COUNT{m_axis_tlast_reg}};
|
||||||
assign m_axis_tid = ID_ENABLE ? {M_COUNT{m_axis_tid_reg}} : {M_COUNT*ID_WIDTH{1'b0}};
|
assign m_axis_tid = ID_ENABLE ? {M_COUNT{m_axis_tid_reg}} : {M_COUNT*ID_WIDTH{1'b0}};
|
||||||
assign m_axis_tdest = DEST_ENABLE ? {M_COUNT{m_axis_tdest_reg}} : {M_COUNT*DEST_WIDTH{1'b0}};
|
assign m_axis_tdest = DEST_ENABLE ? {M_COUNT{m_axis_tdest_reg}} : {M_COUNT*M_DEST_WIDTH_INT{1'b0}};
|
||||||
assign m_axis_tuser = USER_ENABLE ? {M_COUNT{m_axis_tuser_reg}} : {M_COUNT*USER_WIDTH{1'b0}};
|
assign m_axis_tuser = USER_ENABLE ? {M_COUNT{m_axis_tuser_reg}} : {M_COUNT*USER_WIDTH{1'b0}};
|
||||||
|
|
||||||
// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input)
|
// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input)
|
||||||
|
@ -82,49 +82,52 @@ module {{name}} #
|
|||||||
parameter ID_WIDTH = 8,
|
parameter ID_WIDTH = 8,
|
||||||
// Propagate tdest signal
|
// Propagate tdest signal
|
||||||
parameter DEST_ENABLE = 0,
|
parameter DEST_ENABLE = 0,
|
||||||
// tdest signal width
|
// output tdest signal width
|
||||||
parameter DEST_WIDTH = 8,
|
parameter M_DEST_WIDTH = 1,
|
||||||
|
// input tdest signal width
|
||||||
|
parameter S_DEST_WIDTH = M_DEST_WIDTH+{{cn}},
|
||||||
// Propagate tuser signal
|
// Propagate tuser signal
|
||||||
parameter USER_ENABLE = 1,
|
parameter USER_ENABLE = 1,
|
||||||
// tuser signal width
|
// tuser signal width
|
||||||
parameter USER_WIDTH = 1
|
parameter USER_WIDTH = 1,
|
||||||
|
// route via tdest
|
||||||
|
parameter TDEST_ROUTE = 0
|
||||||
)
|
)
|
||||||
(
|
(
|
||||||
input wire clk,
|
input wire clk,
|
||||||
input wire rst,
|
input wire rst,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AXI Stream input
|
* AXI Stream input
|
||||||
*/
|
*/
|
||||||
input wire [DATA_WIDTH-1:0] s_axis_tdata,
|
input wire [DATA_WIDTH-1:0] s_axis_tdata,
|
||||||
input wire [KEEP_WIDTH-1:0] s_axis_tkeep,
|
input wire [KEEP_WIDTH-1:0] s_axis_tkeep,
|
||||||
input wire s_axis_tvalid,
|
input wire s_axis_tvalid,
|
||||||
output wire s_axis_tready,
|
output wire s_axis_tready,
|
||||||
input wire s_axis_tlast,
|
input wire s_axis_tlast,
|
||||||
input wire [ID_WIDTH-1:0] s_axis_tid,
|
input wire [ID_WIDTH-1:0] s_axis_tid,
|
||||||
input wire [DEST_WIDTH-1:0] s_axis_tdest,
|
input wire [S_DEST_WIDTH-1:0] s_axis_tdest,
|
||||||
input wire [USER_WIDTH-1:0] s_axis_tuser,
|
input wire [USER_WIDTH-1:0] s_axis_tuser,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AXI Stream outputs
|
* AXI Stream outputs
|
||||||
*/
|
*/
|
||||||
{%- for p in range(n) %}
|
{%- for p in range(n) %}
|
||||||
output wire [DATA_WIDTH-1:0] m{{'%02d'%p}}_axis_tdata,
|
output wire [DATA_WIDTH-1:0] m{{'%02d'%p}}_axis_tdata,
|
||||||
output wire [KEEP_WIDTH-1:0] m{{'%02d'%p}}_axis_tkeep,
|
output wire [KEEP_WIDTH-1:0] m{{'%02d'%p}}_axis_tkeep,
|
||||||
output wire m{{'%02d'%p}}_axis_tvalid,
|
output wire m{{'%02d'%p}}_axis_tvalid,
|
||||||
input wire m{{'%02d'%p}}_axis_tready,
|
input wire m{{'%02d'%p}}_axis_tready,
|
||||||
output wire m{{'%02d'%p}}_axis_tlast,
|
output wire m{{'%02d'%p}}_axis_tlast,
|
||||||
output wire [ID_WIDTH-1:0] m{{'%02d'%p}}_axis_tid,
|
output wire [ID_WIDTH-1:0] m{{'%02d'%p}}_axis_tid,
|
||||||
output wire [DEST_WIDTH-1:0] m{{'%02d'%p}}_axis_tdest,
|
output wire [M_DEST_WIDTH-1:0] m{{'%02d'%p}}_axis_tdest,
|
||||||
output wire [USER_WIDTH-1:0] m{{'%02d'%p}}_axis_tuser,
|
output wire [USER_WIDTH-1:0] m{{'%02d'%p}}_axis_tuser,
|
||||||
{% endfor -%}
|
{% endfor %}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Control
|
* Control
|
||||||
*/
|
*/
|
||||||
input wire enable,
|
input wire enable,
|
||||||
input wire drop,
|
input wire drop,
|
||||||
input wire [{{cn-1}}:0] select
|
input wire [{{cn-1}}:0] select
|
||||||
);
|
);
|
||||||
|
|
||||||
axis_demux #(
|
axis_demux #(
|
||||||
@ -135,9 +138,11 @@ axis_demux #(
|
|||||||
.ID_ENABLE(ID_ENABLE),
|
.ID_ENABLE(ID_ENABLE),
|
||||||
.ID_WIDTH(ID_WIDTH),
|
.ID_WIDTH(ID_WIDTH),
|
||||||
.DEST_ENABLE(DEST_ENABLE),
|
.DEST_ENABLE(DEST_ENABLE),
|
||||||
.DEST_WIDTH(DEST_WIDTH),
|
.S_DEST_WIDTH(S_DEST_WIDTH),
|
||||||
|
.M_DEST_WIDTH(M_DEST_WIDTH),
|
||||||
.USER_ENABLE(USER_ENABLE),
|
.USER_ENABLE(USER_ENABLE),
|
||||||
.USER_WIDTH(USER_WIDTH)
|
.USER_WIDTH(USER_WIDTH),
|
||||||
|
.TDEST_ROUTE(TDEST_ROUTE)
|
||||||
)
|
)
|
||||||
axis_demux_inst (
|
axis_demux_inst (
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
|
@ -61,11 +61,15 @@ module axis_ram_switch #
|
|||||||
parameter M_KEEP_WIDTH = (M_DATA_WIDTH/8),
|
parameter M_KEEP_WIDTH = (M_DATA_WIDTH/8),
|
||||||
// Propagate tid signal
|
// Propagate tid signal
|
||||||
parameter ID_ENABLE = 0,
|
parameter ID_ENABLE = 0,
|
||||||
// tid signal width
|
// input tid signal width
|
||||||
parameter ID_WIDTH = 8,
|
parameter S_ID_WIDTH = 8,
|
||||||
// tdest signal width
|
// output tid signal width
|
||||||
|
parameter M_ID_WIDTH = S_ID_WIDTH+$clog2(S_COUNT),
|
||||||
|
// output tdest signal width
|
||||||
|
parameter M_DEST_WIDTH = 1,
|
||||||
|
// input tdest signal width
|
||||||
// must be wide enough to uniquely address outputs
|
// must be wide enough to uniquely address outputs
|
||||||
parameter DEST_WIDTH = $clog2(M_COUNT),
|
parameter S_DEST_WIDTH = M_DEST_WIDTH+$clog2(M_COUNT),
|
||||||
// Propagate tuser signal
|
// Propagate tuser signal
|
||||||
parameter USER_ENABLE = 1,
|
parameter USER_ENABLE = 1,
|
||||||
// tuser signal width
|
// tuser signal width
|
||||||
@ -80,18 +84,20 @@ module axis_ram_switch #
|
|||||||
// When set, s_axis_tready is always asserted
|
// When set, s_axis_tready is always asserted
|
||||||
parameter DROP_WHEN_FULL = 0,
|
parameter DROP_WHEN_FULL = 0,
|
||||||
// Output interface routing base tdest selection
|
// Output interface routing base tdest selection
|
||||||
// Concatenate M_COUNT DEST_WIDTH sized constants
|
// Concatenate M_COUNT S_DEST_WIDTH sized constants
|
||||||
// Port selected if M_BASE <= tdest <= M_TOP
|
// Port selected if M_BASE <= tdest <= M_TOP
|
||||||
// set to zero for default routing with tdest MSBs as port index
|
// set to zero for default routing with tdest MSBs as port index
|
||||||
parameter M_BASE = 0,
|
parameter M_BASE = 0,
|
||||||
// Output interface routing top tdest selection
|
// Output interface routing top tdest selection
|
||||||
// Concatenate M_COUNT DEST_WIDTH sized constants
|
// Concatenate M_COUNT S_DEST_WIDTH sized constants
|
||||||
// Port selected if M_BASE <= tdest <= M_TOP
|
// Port selected if M_BASE <= tdest <= M_TOP
|
||||||
// set to zero to inherit from M_BASE
|
// set to zero to inherit from M_BASE
|
||||||
parameter M_TOP = 0,
|
parameter M_TOP = 0,
|
||||||
// Interface connection control
|
// Interface connection control
|
||||||
// M_COUNT concatenated fields of S_COUNT bits
|
// M_COUNT concatenated fields of S_COUNT bits
|
||||||
parameter M_CONNECT = {M_COUNT{{S_COUNT{1'b1}}}},
|
parameter M_CONNECT = {M_COUNT{{S_COUNT{1'b1}}}},
|
||||||
|
// Update tid with routing information
|
||||||
|
parameter UPDATE_TID = 0,
|
||||||
// select round robin arbitration
|
// select round robin arbitration
|
||||||
parameter ARB_TYPE_ROUND_ROBIN = 1,
|
parameter ARB_TYPE_ROUND_ROBIN = 1,
|
||||||
// LSB priority selection
|
// LSB priority selection
|
||||||
@ -100,44 +106,47 @@ module axis_ram_switch #
|
|||||||
parameter RAM_PIPELINE = 2
|
parameter RAM_PIPELINE = 2
|
||||||
)
|
)
|
||||||
(
|
(
|
||||||
input wire clk,
|
input wire clk,
|
||||||
input wire rst,
|
input wire rst,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AXI Stream inputs
|
* AXI Stream inputs
|
||||||
*/
|
*/
|
||||||
input wire [S_COUNT*S_DATA_WIDTH-1:0] s_axis_tdata,
|
input wire [S_COUNT*S_DATA_WIDTH-1:0] s_axis_tdata,
|
||||||
input wire [S_COUNT*S_KEEP_WIDTH-1:0] s_axis_tkeep,
|
input wire [S_COUNT*S_KEEP_WIDTH-1:0] s_axis_tkeep,
|
||||||
input wire [S_COUNT-1:0] s_axis_tvalid,
|
input wire [S_COUNT-1:0] s_axis_tvalid,
|
||||||
output wire [S_COUNT-1:0] s_axis_tready,
|
output wire [S_COUNT-1:0] s_axis_tready,
|
||||||
input wire [S_COUNT-1:0] s_axis_tlast,
|
input wire [S_COUNT-1:0] s_axis_tlast,
|
||||||
input wire [S_COUNT*ID_WIDTH-1:0] s_axis_tid,
|
input wire [S_COUNT*S_ID_WIDTH-1:0] s_axis_tid,
|
||||||
input wire [S_COUNT*DEST_WIDTH-1:0] s_axis_tdest,
|
input wire [S_COUNT*S_DEST_WIDTH-1:0] s_axis_tdest,
|
||||||
input wire [S_COUNT*USER_WIDTH-1:0] s_axis_tuser,
|
input wire [S_COUNT*USER_WIDTH-1:0] s_axis_tuser,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AXI Stream outputs
|
* AXI Stream outputs
|
||||||
*/
|
*/
|
||||||
output wire [M_COUNT*M_DATA_WIDTH-1:0] m_axis_tdata,
|
output wire [M_COUNT*M_DATA_WIDTH-1:0] m_axis_tdata,
|
||||||
output wire [M_COUNT*M_KEEP_WIDTH-1:0] m_axis_tkeep,
|
output wire [M_COUNT*M_KEEP_WIDTH-1:0] m_axis_tkeep,
|
||||||
output wire [M_COUNT-1:0] m_axis_tvalid,
|
output wire [M_COUNT-1:0] m_axis_tvalid,
|
||||||
input wire [M_COUNT-1:0] m_axis_tready,
|
input wire [M_COUNT-1:0] m_axis_tready,
|
||||||
output wire [M_COUNT-1:0] m_axis_tlast,
|
output wire [M_COUNT-1:0] m_axis_tlast,
|
||||||
output wire [M_COUNT*ID_WIDTH-1:0] m_axis_tid,
|
output wire [M_COUNT*M_ID_WIDTH-1:0] m_axis_tid,
|
||||||
output wire [M_COUNT*DEST_WIDTH-1:0] m_axis_tdest,
|
output wire [M_COUNT*M_DEST_WIDTH-1:0] m_axis_tdest,
|
||||||
output wire [M_COUNT*USER_WIDTH-1:0] m_axis_tuser,
|
output wire [M_COUNT*USER_WIDTH-1:0] m_axis_tuser,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Status
|
* Status
|
||||||
*/
|
*/
|
||||||
output wire [S_COUNT-1:0] status_overflow,
|
output wire [S_COUNT-1:0] status_overflow,
|
||||||
output wire [S_COUNT-1:0] status_bad_frame,
|
output wire [S_COUNT-1:0] status_bad_frame,
|
||||||
output wire [S_COUNT-1:0] status_good_frame
|
output wire [S_COUNT-1:0] status_good_frame
|
||||||
);
|
);
|
||||||
|
|
||||||
parameter CL_S_COUNT = $clog2(S_COUNT);
|
parameter CL_S_COUNT = $clog2(S_COUNT);
|
||||||
parameter CL_M_COUNT = $clog2(M_COUNT);
|
parameter CL_M_COUNT = $clog2(M_COUNT);
|
||||||
|
|
||||||
|
parameter S_ID_WIDTH_INT = S_ID_WIDTH > 0 ? S_ID_WIDTH : 1;
|
||||||
|
parameter M_DEST_WIDTH_INT = M_DEST_WIDTH > 0 ? M_DEST_WIDTH : 1;
|
||||||
|
|
||||||
// force keep width to 1 when disabled
|
// force keep width to 1 when disabled
|
||||||
parameter S_KEEP_WIDTH_INT = S_KEEP_ENABLE ? S_KEEP_WIDTH : 1;
|
parameter S_KEEP_WIDTH_INT = S_KEEP_ENABLE ? S_KEEP_WIDTH : 1;
|
||||||
parameter M_KEEP_WIDTH_INT = M_KEEP_ENABLE ? M_KEEP_WIDTH : 1;
|
parameter M_KEEP_WIDTH_INT = M_KEEP_ENABLE ? M_KEEP_WIDTH : 1;
|
||||||
@ -179,30 +188,42 @@ initial begin
|
|||||||
$finish;
|
$finish;
|
||||||
end
|
end
|
||||||
|
|
||||||
if (DEST_WIDTH < CL_M_COUNT) begin
|
if (S_DEST_WIDTH < CL_M_COUNT) begin
|
||||||
$error("Error: DEST_WIDTH too small for port count (instance %m)");
|
$error("Error: S_DEST_WIDTH too small for port count (instance %m)");
|
||||||
$finish;
|
$finish;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if (UPDATE_TID) begin
|
||||||
|
if (!ID_ENABLE) begin
|
||||||
|
$error("Error: UPDATE_TID set requires ID_ENABLE set (instance %m)");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (M_ID_WIDTH < CL_S_COUNT) begin
|
||||||
|
$error("Error: M_ID_WIDTH too small for port count (instance %m)");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if (M_BASE == 0) begin
|
if (M_BASE == 0) begin
|
||||||
// M_BASE is zero, route with tdest as port index
|
// M_BASE is zero, route with tdest as port index
|
||||||
$display("Addressing configuration for axis_switch instance %m");
|
$display("Addressing configuration for axis_switch instance %m");
|
||||||
for (i = 0; i < M_COUNT; i = i + 1) begin
|
for (i = 0; i < M_COUNT; i = i + 1) begin
|
||||||
$display("%d: %08x-%08x (connect mask %b)", i, i << (DEST_WIDTH-CL_M_COUNT), ((i+1) << (DEST_WIDTH-CL_M_COUNT))-1, M_CONNECT[i*S_COUNT +: S_COUNT]);
|
$display("%d: %08x-%08x (connect mask %b)", i, i << (S_DEST_WIDTH-CL_M_COUNT), ((i+1) << (S_DEST_WIDTH-CL_M_COUNT))-1, M_CONNECT[i*S_COUNT +: S_COUNT]);
|
||||||
end
|
end
|
||||||
|
|
||||||
end else if (M_TOP == 0) begin
|
end else if (M_TOP == 0) begin
|
||||||
// M_TOP is zero, assume equal to M_BASE
|
// M_TOP is zero, assume equal to M_BASE
|
||||||
$display("Addressing configuration for axis_switch instance %m");
|
$display("Addressing configuration for axis_switch instance %m");
|
||||||
for (i = 0; i < M_COUNT; i = i + 1) begin
|
for (i = 0; i < M_COUNT; i = i + 1) begin
|
||||||
$display("%d: %08x (connect mask %b)", i, M_BASE[i*DEST_WIDTH +: DEST_WIDTH], M_CONNECT[i*S_COUNT +: S_COUNT]);
|
$display("%d: %08x (connect mask %b)", i, M_BASE[i*S_DEST_WIDTH +: S_DEST_WIDTH], M_CONNECT[i*S_COUNT +: S_COUNT]);
|
||||||
end
|
end
|
||||||
|
|
||||||
for (i = 0; i < M_COUNT; i = i + 1) begin
|
for (i = 0; i < M_COUNT; i = i + 1) begin
|
||||||
for (j = i+1; j < M_COUNT; j = j + 1) begin
|
for (j = i+1; j < M_COUNT; j = j + 1) begin
|
||||||
if (M_BASE[i*DEST_WIDTH +: DEST_WIDTH] == M_BASE[j*DEST_WIDTH +: DEST_WIDTH]) begin
|
if (M_BASE[i*S_DEST_WIDTH +: S_DEST_WIDTH] == M_BASE[j*S_DEST_WIDTH +: S_DEST_WIDTH]) begin
|
||||||
$display("%d: %08x", i, M_BASE[i*DEST_WIDTH +: DEST_WIDTH]);
|
$display("%d: %08x", i, M_BASE[i*S_DEST_WIDTH +: S_DEST_WIDTH]);
|
||||||
$display("%d: %08x", j, M_BASE[j*DEST_WIDTH +: DEST_WIDTH]);
|
$display("%d: %08x", j, M_BASE[j*S_DEST_WIDTH +: S_DEST_WIDTH]);
|
||||||
$error("Error: ranges overlap (instance %m)");
|
$error("Error: ranges overlap (instance %m)");
|
||||||
$finish;
|
$finish;
|
||||||
end
|
end
|
||||||
@ -211,11 +232,11 @@ initial begin
|
|||||||
end else begin
|
end else begin
|
||||||
$display("Addressing configuration for axis_switch instance %m");
|
$display("Addressing configuration for axis_switch instance %m");
|
||||||
for (i = 0; i < M_COUNT; i = i + 1) begin
|
for (i = 0; i < M_COUNT; i = i + 1) begin
|
||||||
$display("%d: %08x-%08x (connect mask %b)", i, M_BASE[i*DEST_WIDTH +: DEST_WIDTH], M_TOP[i*DEST_WIDTH +: DEST_WIDTH], M_CONNECT[i*S_COUNT +: S_COUNT]);
|
$display("%d: %08x-%08x (connect mask %b)", i, M_BASE[i*S_DEST_WIDTH +: S_DEST_WIDTH], M_TOP[i*S_DEST_WIDTH +: S_DEST_WIDTH], M_CONNECT[i*S_COUNT +: S_COUNT]);
|
||||||
end
|
end
|
||||||
|
|
||||||
for (i = 0; i < M_COUNT; i = i + 1) begin
|
for (i = 0; i < M_COUNT; i = i + 1) begin
|
||||||
if (M_BASE[i*DEST_WIDTH +: DEST_WIDTH] > M_TOP[i*DEST_WIDTH +: DEST_WIDTH]) begin
|
if (M_BASE[i*S_DEST_WIDTH +: S_DEST_WIDTH] > M_TOP[i*S_DEST_WIDTH +: S_DEST_WIDTH]) begin
|
||||||
$error("Error: invalid range (instance %m)");
|
$error("Error: invalid range (instance %m)");
|
||||||
$finish;
|
$finish;
|
||||||
end
|
end
|
||||||
@ -223,9 +244,9 @@ initial begin
|
|||||||
|
|
||||||
for (i = 0; i < M_COUNT; i = i + 1) begin
|
for (i = 0; i < M_COUNT; i = i + 1) begin
|
||||||
for (j = i+1; j < M_COUNT; j = j + 1) begin
|
for (j = i+1; j < M_COUNT; j = j + 1) begin
|
||||||
if (M_BASE[i*DEST_WIDTH +: DEST_WIDTH] <= M_TOP[j*DEST_WIDTH +: DEST_WIDTH] && M_BASE[j*DEST_WIDTH +: DEST_WIDTH] <= M_TOP[i*DEST_WIDTH +: DEST_WIDTH]) begin
|
if (M_BASE[i*S_DEST_WIDTH +: S_DEST_WIDTH] <= M_TOP[j*S_DEST_WIDTH +: S_DEST_WIDTH] && M_BASE[j*S_DEST_WIDTH +: S_DEST_WIDTH] <= M_TOP[i*S_DEST_WIDTH +: S_DEST_WIDTH]) begin
|
||||||
$display("%d: %08x-%08x", i, M_BASE[i*DEST_WIDTH +: DEST_WIDTH], M_TOP[i*DEST_WIDTH +: DEST_WIDTH]);
|
$display("%d: %08x-%08x", i, M_BASE[i*S_DEST_WIDTH +: S_DEST_WIDTH], M_TOP[i*S_DEST_WIDTH +: S_DEST_WIDTH]);
|
||||||
$display("%d: %08x-%08x", j, M_BASE[j*DEST_WIDTH +: DEST_WIDTH], M_TOP[j*DEST_WIDTH +: DEST_WIDTH]);
|
$display("%d: %08x-%08x", j, M_BASE[j*S_DEST_WIDTH +: S_DEST_WIDTH], M_TOP[j*S_DEST_WIDTH +: S_DEST_WIDTH]);
|
||||||
$error("Error: ranges overlap (instance %m)");
|
$error("Error: ranges overlap (instance %m)");
|
||||||
$finish;
|
$finish;
|
||||||
end
|
end
|
||||||
@ -349,21 +370,21 @@ always @(posedge clk) begin
|
|||||||
end
|
end
|
||||||
|
|
||||||
// Interconnect
|
// Interconnect
|
||||||
wire [S_COUNT*RAM_ADDR_WIDTH-1:0] int_cmd_addr;
|
wire [S_COUNT*RAM_ADDR_WIDTH-1:0] int_cmd_addr;
|
||||||
wire [S_COUNT*ADDR_WIDTH-1:0] int_cmd_len;
|
wire [S_COUNT*ADDR_WIDTH-1:0] int_cmd_len;
|
||||||
wire [S_COUNT*CMD_ADDR_WIDTH-1:0] int_cmd_id;
|
wire [S_COUNT*CMD_ADDR_WIDTH-1:0] int_cmd_id;
|
||||||
wire [S_COUNT*KEEP_WIDTH-1:0] int_cmd_tkeep;
|
wire [S_COUNT*KEEP_WIDTH-1:0] int_cmd_tkeep;
|
||||||
wire [S_COUNT*ID_WIDTH-1:0] int_cmd_tid;
|
wire [S_COUNT*S_ID_WIDTH-1:0] int_cmd_tid;
|
||||||
wire [S_COUNT*DEST_WIDTH-1:0] int_cmd_tdest;
|
wire [S_COUNT*S_DEST_WIDTH-1:0] int_cmd_tdest;
|
||||||
wire [S_COUNT*USER_WIDTH-1:0] int_cmd_tuser;
|
wire [S_COUNT*USER_WIDTH-1:0] int_cmd_tuser;
|
||||||
|
|
||||||
wire [S_COUNT*M_COUNT-1:0] int_cmd_valid;
|
wire [S_COUNT*M_COUNT-1:0] int_cmd_valid;
|
||||||
wire [M_COUNT*S_COUNT-1:0] int_cmd_ready;
|
wire [M_COUNT*S_COUNT-1:0] int_cmd_ready;
|
||||||
|
|
||||||
wire [M_COUNT*CMD_ADDR_WIDTH-1:0] int_cmd_status_id;
|
wire [M_COUNT*CMD_ADDR_WIDTH-1:0] int_cmd_status_id;
|
||||||
|
|
||||||
wire [M_COUNT*S_COUNT-1:0] int_cmd_status_valid;
|
wire [M_COUNT*S_COUNT-1:0] int_cmd_status_valid;
|
||||||
wire [S_COUNT*M_COUNT-1:0] int_cmd_status_ready;
|
wire [S_COUNT*M_COUNT-1:0] int_cmd_status_ready;
|
||||||
|
|
||||||
generate
|
generate
|
||||||
|
|
||||||
@ -371,14 +392,14 @@ generate
|
|||||||
|
|
||||||
for (m = 0; m < S_COUNT; m = m + 1) begin : s_ifaces
|
for (m = 0; m < S_COUNT; m = m + 1) begin : s_ifaces
|
||||||
|
|
||||||
wire [DATA_WIDTH-1:0] port_axis_tdata;
|
wire [DATA_WIDTH-1:0] port_axis_tdata;
|
||||||
wire [KEEP_WIDTH-1:0] port_axis_tkeep;
|
wire [KEEP_WIDTH-1:0] port_axis_tkeep;
|
||||||
wire port_axis_tvalid;
|
wire port_axis_tvalid;
|
||||||
wire port_axis_tready;
|
wire port_axis_tready;
|
||||||
wire port_axis_tlast;
|
wire port_axis_tlast;
|
||||||
wire [ID_WIDTH-1:0] port_axis_tid;
|
wire [S_ID_WIDTH-1:0] port_axis_tid;
|
||||||
wire [DEST_WIDTH-1:0] port_axis_tdest;
|
wire [S_DEST_WIDTH-1:0] port_axis_tdest;
|
||||||
wire [USER_WIDTH-1:0] port_axis_tuser;
|
wire [USER_WIDTH-1:0] port_axis_tuser;
|
||||||
|
|
||||||
axis_adapter #(
|
axis_adapter #(
|
||||||
.S_DATA_WIDTH(S_DATA_WIDTH),
|
.S_DATA_WIDTH(S_DATA_WIDTH),
|
||||||
@ -387,10 +408,10 @@ generate
|
|||||||
.M_DATA_WIDTH(DATA_WIDTH),
|
.M_DATA_WIDTH(DATA_WIDTH),
|
||||||
.M_KEEP_ENABLE(1),
|
.M_KEEP_ENABLE(1),
|
||||||
.M_KEEP_WIDTH(KEEP_WIDTH),
|
.M_KEEP_WIDTH(KEEP_WIDTH),
|
||||||
.ID_ENABLE(ID_ENABLE),
|
.ID_ENABLE(ID_ENABLE && S_ID_WIDTH > 0),
|
||||||
.ID_WIDTH(ID_WIDTH),
|
.ID_WIDTH(S_ID_WIDTH_INT),
|
||||||
.DEST_ENABLE(1),
|
.DEST_ENABLE(1),
|
||||||
.DEST_WIDTH(DEST_WIDTH),
|
.DEST_WIDTH(S_DEST_WIDTH),
|
||||||
.USER_ENABLE(USER_ENABLE),
|
.USER_ENABLE(USER_ENABLE),
|
||||||
.USER_WIDTH(USER_WIDTH)
|
.USER_WIDTH(USER_WIDTH)
|
||||||
)
|
)
|
||||||
@ -403,8 +424,8 @@ generate
|
|||||||
.s_axis_tvalid(s_axis_tvalid[m]),
|
.s_axis_tvalid(s_axis_tvalid[m]),
|
||||||
.s_axis_tready(s_axis_tready[m]),
|
.s_axis_tready(s_axis_tready[m]),
|
||||||
.s_axis_tlast(s_axis_tlast[m]),
|
.s_axis_tlast(s_axis_tlast[m]),
|
||||||
.s_axis_tid(s_axis_tid[ID_WIDTH*m +: ID_WIDTH]),
|
.s_axis_tid(s_axis_tid[S_ID_WIDTH*m +: S_ID_WIDTH_INT]),
|
||||||
.s_axis_tdest(s_axis_tdest[DEST_WIDTH*m +: DEST_WIDTH]),
|
.s_axis_tdest(s_axis_tdest[S_DEST_WIDTH*m +: S_DEST_WIDTH]),
|
||||||
.s_axis_tuser(s_axis_tuser[USER_WIDTH*m +: USER_WIDTH]),
|
.s_axis_tuser(s_axis_tuser[USER_WIDTH*m +: USER_WIDTH]),
|
||||||
// AXI output
|
// AXI output
|
||||||
.m_axis_tdata(port_axis_tdata),
|
.m_axis_tdata(port_axis_tdata),
|
||||||
@ -442,7 +463,7 @@ generate
|
|||||||
drop_next = 1'b0;
|
drop_next = 1'b0;
|
||||||
end else begin
|
end else begin
|
||||||
// M_BASE is zero, route with $clog2(M_COUNT) MSBs of tdest as port index
|
// M_BASE is zero, route with $clog2(M_COUNT) MSBs of tdest as port index
|
||||||
if (port_axis_tdest[DEST_WIDTH-CL_M_COUNT +: CL_M_COUNT] == k && (M_CONNECT & (1 << (m+k*S_COUNT)))) begin
|
if (port_axis_tdest[S_DEST_WIDTH-CL_M_COUNT +: CL_M_COUNT] == k && (M_CONNECT & (1 << (m+k*S_COUNT)))) begin
|
||||||
select_next = k;
|
select_next = k;
|
||||||
select_valid_next = 1'b1;
|
select_valid_next = 1'b1;
|
||||||
drop_next = 1'b0;
|
drop_next = 1'b0;
|
||||||
@ -450,13 +471,13 @@ generate
|
|||||||
end
|
end
|
||||||
end else if (M_TOP == 0) begin
|
end else if (M_TOP == 0) begin
|
||||||
// M_TOP is zero, assume equal to M_BASE
|
// M_TOP is zero, assume equal to M_BASE
|
||||||
if (port_axis_tdest == M_BASE[k*DEST_WIDTH +: DEST_WIDTH] && (M_CONNECT & (1 << (m+k*S_COUNT)))) begin
|
if (port_axis_tdest == M_BASE[k*S_DEST_WIDTH +: S_DEST_WIDTH] && (M_CONNECT & (1 << (m+k*S_COUNT)))) begin
|
||||||
select_next = k;
|
select_next = k;
|
||||||
select_valid_next = 1'b1;
|
select_valid_next = 1'b1;
|
||||||
drop_next = 1'b0;
|
drop_next = 1'b0;
|
||||||
end
|
end
|
||||||
end else begin
|
end else begin
|
||||||
if (port_axis_tdest >= M_BASE[k*DEST_WIDTH +: DEST_WIDTH] && port_axis_tdest <= M_TOP[k*DEST_WIDTH +: DEST_WIDTH] && (M_CONNECT & (1 << (m+k*S_COUNT)))) begin
|
if (port_axis_tdest >= M_BASE[k*S_DEST_WIDTH +: S_DEST_WIDTH] && port_axis_tdest <= M_TOP[k*S_DEST_WIDTH +: S_DEST_WIDTH] && (M_CONNECT & (1 << (m+k*S_COUNT)))) begin
|
||||||
select_next = k;
|
select_next = k;
|
||||||
select_valid_next = 1'b1;
|
select_valid_next = 1'b1;
|
||||||
drop_next = 1'b0;
|
drop_next = 1'b0;
|
||||||
@ -542,8 +563,8 @@ generate
|
|||||||
reg [ADDR_WIDTH-1:0] cmd_table_len[2**CMD_ADDR_WIDTH-1:0];
|
reg [ADDR_WIDTH-1:0] cmd_table_len[2**CMD_ADDR_WIDTH-1:0];
|
||||||
reg [CL_M_COUNT-1:0] cmd_table_select[2**CMD_ADDR_WIDTH-1:0];
|
reg [CL_M_COUNT-1:0] cmd_table_select[2**CMD_ADDR_WIDTH-1:0];
|
||||||
reg [KEEP_WIDTH-1:0] cmd_table_tkeep[2**CMD_ADDR_WIDTH-1:0];
|
reg [KEEP_WIDTH-1:0] cmd_table_tkeep[2**CMD_ADDR_WIDTH-1:0];
|
||||||
reg [ID_WIDTH-1:0] cmd_table_tid[2**CMD_ADDR_WIDTH-1:0];
|
reg [S_ID_WIDTH-1:0] cmd_table_tid[2**CMD_ADDR_WIDTH-1:0];
|
||||||
reg [DEST_WIDTH-1:0] cmd_table_tdest[2**CMD_ADDR_WIDTH-1:0];
|
reg [S_DEST_WIDTH-1:0] cmd_table_tdest[2**CMD_ADDR_WIDTH-1:0];
|
||||||
reg [USER_WIDTH-1:0] cmd_table_tuser[2**CMD_ADDR_WIDTH-1:0];
|
reg [USER_WIDTH-1:0] cmd_table_tuser[2**CMD_ADDR_WIDTH-1:0];
|
||||||
|
|
||||||
reg [CMD_ADDR_WIDTH+1-1:0] cmd_table_start_ptr_reg = 0;
|
reg [CMD_ADDR_WIDTH+1-1:0] cmd_table_start_ptr_reg = 0;
|
||||||
@ -552,8 +573,8 @@ generate
|
|||||||
reg [ADDR_WIDTH-1:0] cmd_table_start_len;
|
reg [ADDR_WIDTH-1:0] cmd_table_start_len;
|
||||||
reg [CL_M_COUNT-1:0] cmd_table_start_select;
|
reg [CL_M_COUNT-1:0] cmd_table_start_select;
|
||||||
reg [KEEP_WIDTH-1:0] cmd_table_start_tkeep;
|
reg [KEEP_WIDTH-1:0] cmd_table_start_tkeep;
|
||||||
reg [ID_WIDTH-1:0] cmd_table_start_tid;
|
reg [S_ID_WIDTH-1:0] cmd_table_start_tid;
|
||||||
reg [DEST_WIDTH-1:0] cmd_table_start_tdest;
|
reg [S_DEST_WIDTH-1:0] cmd_table_start_tdest;
|
||||||
reg [USER_WIDTH-1:0] cmd_table_start_tuser;
|
reg [USER_WIDTH-1:0] cmd_table_start_tuser;
|
||||||
reg cmd_table_start_en;
|
reg cmd_table_start_en;
|
||||||
reg [CMD_ADDR_WIDTH+1-1:0] cmd_table_read_ptr_reg = 0;
|
reg [CMD_ADDR_WIDTH+1-1:0] cmd_table_read_ptr_reg = 0;
|
||||||
@ -563,14 +584,14 @@ generate
|
|||||||
reg [CMD_ADDR_WIDTH+1-1:0] cmd_table_finish_ptr_reg = 0;
|
reg [CMD_ADDR_WIDTH+1-1:0] cmd_table_finish_ptr_reg = 0;
|
||||||
reg cmd_table_finish_en;
|
reg cmd_table_finish_en;
|
||||||
|
|
||||||
reg [RAM_ADDR_WIDTH-1:0] cmd_addr_reg = {RAM_ADDR_WIDTH{1'b0}}, cmd_addr_next;
|
reg [RAM_ADDR_WIDTH-1:0] cmd_addr_reg = {RAM_ADDR_WIDTH{1'b0}}, cmd_addr_next;
|
||||||
reg [ADDR_WIDTH-1:0] cmd_len_reg = {ADDR_WIDTH{1'b0}}, cmd_len_next;
|
reg [ADDR_WIDTH-1:0] cmd_len_reg = {ADDR_WIDTH{1'b0}}, cmd_len_next;
|
||||||
reg [CMD_ADDR_WIDTH-1:0] cmd_id_reg = {CMD_ADDR_WIDTH{1'b0}}, cmd_id_next;
|
reg [CMD_ADDR_WIDTH-1:0] cmd_id_reg = {CMD_ADDR_WIDTH{1'b0}}, cmd_id_next;
|
||||||
reg [KEEP_WIDTH-1:0] cmd_tkeep_reg = {KEEP_WIDTH{1'b0}}, cmd_tkeep_next;
|
reg [KEEP_WIDTH-1:0] cmd_tkeep_reg = {KEEP_WIDTH{1'b0}}, cmd_tkeep_next;
|
||||||
reg [ID_WIDTH-1:0] cmd_tid_reg = {ID_WIDTH{1'b0}}, cmd_tid_next;
|
reg [S_ID_WIDTH-1:0] cmd_tid_reg = {S_ID_WIDTH_INT{1'b0}}, cmd_tid_next;
|
||||||
reg [DEST_WIDTH-1:0] cmd_tdest_reg = {DEST_WIDTH{1'b0}}, cmd_tdest_next;
|
reg [S_DEST_WIDTH-1:0] cmd_tdest_reg = {S_DEST_WIDTH{1'b0}}, cmd_tdest_next;
|
||||||
reg [USER_WIDTH-1:0] cmd_tuser_reg = {USER_WIDTH{1'b0}}, cmd_tuser_next;
|
reg [USER_WIDTH-1:0] cmd_tuser_reg = {USER_WIDTH{1'b0}}, cmd_tuser_next;
|
||||||
reg [M_COUNT-1:0] cmd_valid_reg = 0, cmd_valid_next;
|
reg [M_COUNT-1:0] cmd_valid_reg = 0, cmd_valid_next;
|
||||||
|
|
||||||
reg cmd_status_ready_reg = 1'b0, cmd_status_ready_next;
|
reg cmd_status_ready_reg = 1'b0, cmd_status_ready_next;
|
||||||
|
|
||||||
@ -590,8 +611,8 @@ generate
|
|||||||
assign int_cmd_len[m*ADDR_WIDTH +: ADDR_WIDTH] = cmd_len_reg;
|
assign int_cmd_len[m*ADDR_WIDTH +: ADDR_WIDTH] = cmd_len_reg;
|
||||||
assign int_cmd_id[m*CMD_ADDR_WIDTH +: CMD_ADDR_WIDTH] = cmd_id_reg;
|
assign int_cmd_id[m*CMD_ADDR_WIDTH +: CMD_ADDR_WIDTH] = cmd_id_reg;
|
||||||
assign int_cmd_tkeep[m*KEEP_WIDTH +: KEEP_WIDTH] = cmd_tkeep_reg;
|
assign int_cmd_tkeep[m*KEEP_WIDTH +: KEEP_WIDTH] = cmd_tkeep_reg;
|
||||||
assign int_cmd_tid[m*ID_WIDTH +: ID_WIDTH] = cmd_tid_reg;
|
assign int_cmd_tid[m*S_ID_WIDTH +: S_ID_WIDTH_INT] = cmd_tid_reg;
|
||||||
assign int_cmd_tdest[m*DEST_WIDTH +: DEST_WIDTH] = cmd_tdest_reg;
|
assign int_cmd_tdest[m*S_DEST_WIDTH +: S_DEST_WIDTH] = cmd_tdest_reg;
|
||||||
assign int_cmd_tuser[m*USER_WIDTH +: USER_WIDTH] = cmd_tuser_reg;
|
assign int_cmd_tuser[m*USER_WIDTH +: USER_WIDTH] = cmd_tuser_reg;
|
||||||
assign int_cmd_valid[m*M_COUNT +: M_COUNT] = cmd_valid_reg;
|
assign int_cmd_valid[m*M_COUNT +: M_COUNT] = cmd_valid_reg;
|
||||||
|
|
||||||
@ -821,16 +842,30 @@ generate
|
|||||||
);
|
);
|
||||||
|
|
||||||
// mux
|
// mux
|
||||||
wire [RAM_ADDR_WIDTH-1:0] cmd_addr_mux = int_cmd_addr[grant_encoded*RAM_ADDR_WIDTH +: RAM_ADDR_WIDTH];
|
reg [RAM_ADDR_WIDTH-1:0] cmd_addr_mux;
|
||||||
wire [ADDR_WIDTH-1:0] cmd_len_mux = int_cmd_len[grant_encoded*ADDR_WIDTH +: ADDR_WIDTH];
|
reg [ADDR_WIDTH-1:0] cmd_len_mux;
|
||||||
wire [CMD_ADDR_WIDTH-1:0] cmd_id_mux = int_cmd_id[grant_encoded*CMD_ADDR_WIDTH +: CMD_ADDR_WIDTH];
|
reg [CMD_ADDR_WIDTH-1:0] cmd_id_mux;
|
||||||
wire [KEEP_WIDTH-1:0] cmd_tkeep_mux = int_cmd_tkeep[grant_encoded*KEEP_WIDTH +: KEEP_WIDTH];
|
reg [KEEP_WIDTH-1:0] cmd_tkeep_mux;
|
||||||
wire [ID_WIDTH-1:0] cmd_tid_mux = int_cmd_tid[grant_encoded*ID_WIDTH +: ID_WIDTH];
|
reg [M_ID_WIDTH-1:0] cmd_tid_mux;
|
||||||
wire [DEST_WIDTH-1:0] cmd_tdest_mux = int_cmd_tdest[grant_encoded*DEST_WIDTH +: DEST_WIDTH];
|
reg [M_DEST_WIDTH-1:0] cmd_tdest_mux;
|
||||||
wire [USER_WIDTH-1:0] cmd_tuser_mux = int_cmd_tuser[grant_encoded*USER_WIDTH +: USER_WIDTH];
|
reg [USER_WIDTH-1:0] cmd_tuser_mux;
|
||||||
wire cmd_valid_mux = int_cmd_valid[grant_encoded*M_COUNT+n] && grant_valid;
|
reg cmd_valid_mux;
|
||||||
wire cmd_ready_mux;
|
wire cmd_ready_mux;
|
||||||
|
|
||||||
|
always @* begin
|
||||||
|
cmd_addr_mux = int_cmd_addr[grant_encoded*RAM_ADDR_WIDTH +: RAM_ADDR_WIDTH];
|
||||||
|
cmd_len_mux = int_cmd_len[grant_encoded*ADDR_WIDTH +: ADDR_WIDTH];
|
||||||
|
cmd_id_mux = int_cmd_id[grant_encoded*CMD_ADDR_WIDTH +: CMD_ADDR_WIDTH];
|
||||||
|
cmd_tkeep_mux = int_cmd_tkeep[grant_encoded*KEEP_WIDTH +: KEEP_WIDTH];
|
||||||
|
cmd_tid_mux = int_cmd_tid[grant_encoded*S_ID_WIDTH +: S_ID_WIDTH_INT];
|
||||||
|
if (UPDATE_TID && S_COUNT > 1) begin
|
||||||
|
cmd_tid_mux[M_ID_WIDTH-1:M_ID_WIDTH-CL_S_COUNT] = grant_encoded;
|
||||||
|
end
|
||||||
|
cmd_tdest_mux = int_cmd_tdest[grant_encoded*S_DEST_WIDTH +: S_DEST_WIDTH];
|
||||||
|
cmd_tuser_mux = int_cmd_tuser[grant_encoded*USER_WIDTH +: USER_WIDTH];
|
||||||
|
cmd_valid_mux = int_cmd_valid[grant_encoded*M_COUNT+n] && grant_valid;
|
||||||
|
end
|
||||||
|
|
||||||
assign int_cmd_ready[n*S_COUNT +: S_COUNT] = (grant_valid && cmd_ready_mux) << grant_encoded;
|
assign int_cmd_ready[n*S_COUNT +: S_COUNT] = (grant_valid && cmd_ready_mux) << grant_encoded;
|
||||||
|
|
||||||
for (m = 0; m < S_COUNT; m = m + 1) begin
|
for (m = 0; m < S_COUNT; m = m + 1) begin
|
||||||
@ -846,18 +881,18 @@ generate
|
|||||||
reg [CMD_ADDR_WIDTH-1:0] id_reg = 0, id_next;
|
reg [CMD_ADDR_WIDTH-1:0] id_reg = 0, id_next;
|
||||||
|
|
||||||
reg [KEEP_WIDTH-1:0] last_cycle_tkeep_reg = {KEEP_WIDTH{1'b0}}, last_cycle_tkeep_next;
|
reg [KEEP_WIDTH-1:0] last_cycle_tkeep_reg = {KEEP_WIDTH{1'b0}}, last_cycle_tkeep_next;
|
||||||
reg [ID_WIDTH-1:0] tid_reg = {ID_WIDTH{1'b0}}, tid_next;
|
reg [M_ID_WIDTH-1:0] tid_reg = {M_ID_WIDTH{1'b0}}, tid_next;
|
||||||
reg [DEST_WIDTH-1:0] tdest_reg = {DEST_WIDTH{1'b0}}, tdest_next;
|
reg [M_DEST_WIDTH-1:0] tdest_reg = {M_DEST_WIDTH_INT{1'b0}}, tdest_next;
|
||||||
reg [USER_WIDTH-1:0] tuser_reg = {USER_WIDTH{1'b0}}, tuser_next;
|
reg [USER_WIDTH-1:0] tuser_reg = {USER_WIDTH{1'b0}}, tuser_next;
|
||||||
|
|
||||||
reg [DATA_WIDTH-1:0] out_axis_tdata_reg = {DATA_WIDTH{1'b0}}, out_axis_tdata_next;
|
reg [DATA_WIDTH-1:0] out_axis_tdata_reg = {DATA_WIDTH{1'b0}}, out_axis_tdata_next;
|
||||||
reg [KEEP_WIDTH-1:0] out_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}, out_axis_tkeep_next;
|
reg [KEEP_WIDTH-1:0] out_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}, out_axis_tkeep_next;
|
||||||
reg out_axis_tvalid_reg = 1'b0, out_axis_tvalid_next;
|
reg out_axis_tvalid_reg = 1'b0, out_axis_tvalid_next;
|
||||||
wire out_axis_tready;
|
wire out_axis_tready;
|
||||||
reg out_axis_tlast_reg = 1'b0, out_axis_tlast_next;
|
reg out_axis_tlast_reg = 1'b0, out_axis_tlast_next;
|
||||||
reg [ID_WIDTH-1:0] out_axis_tid_reg = {ID_WIDTH{1'b0}}, out_axis_tid_next;
|
reg [M_ID_WIDTH-1:0] out_axis_tid_reg = {M_ID_WIDTH{1'b0}}, out_axis_tid_next;
|
||||||
reg [DEST_WIDTH-1:0] out_axis_tdest_reg = {DEST_WIDTH{1'b0}}, out_axis_tdest_next;
|
reg [M_DEST_WIDTH-1:0] out_axis_tdest_reg = {M_DEST_WIDTH_INT{1'b0}}, out_axis_tdest_next;
|
||||||
reg [USER_WIDTH-1:0] out_axis_tuser_reg = {USER_WIDTH{1'b0}}, out_axis_tuser_next;
|
reg [USER_WIDTH-1:0] out_axis_tuser_reg = {USER_WIDTH{1'b0}}, out_axis_tuser_next;
|
||||||
|
|
||||||
reg [RAM_ADDR_WIDTH-1:0] ram_rd_addr_reg = {RAM_ADDR_WIDTH{1'b0}}, ram_rd_addr_next;
|
reg [RAM_ADDR_WIDTH-1:0] ram_rd_addr_reg = {RAM_ADDR_WIDTH{1'b0}}, ram_rd_addr_next;
|
||||||
reg ram_rd_en_reg = 1'b0, ram_rd_en_next;
|
reg ram_rd_en_reg = 1'b0, ram_rd_en_next;
|
||||||
@ -878,8 +913,8 @@ generate
|
|||||||
reg [DATA_WIDTH-1:0] out_fifo_tdata[31:0];
|
reg [DATA_WIDTH-1:0] out_fifo_tdata[31:0];
|
||||||
reg [KEEP_WIDTH-1:0] out_fifo_tkeep[31:0];
|
reg [KEEP_WIDTH-1:0] out_fifo_tkeep[31:0];
|
||||||
reg out_fifo_tlast[31:0];
|
reg out_fifo_tlast[31:0];
|
||||||
reg [ID_WIDTH-1:0] out_fifo_tid[31:0];
|
reg [M_ID_WIDTH-1:0] out_fifo_tid[31:0];
|
||||||
reg [DEST_WIDTH-1:0] out_fifo_tdest[31:0];
|
reg [M_DEST_WIDTH-1:0] out_fifo_tdest[31:0];
|
||||||
reg [USER_WIDTH-1:0] out_fifo_tuser[31:0];
|
reg [USER_WIDTH-1:0] out_fifo_tuser[31:0];
|
||||||
|
|
||||||
reg [5:0] out_fifo_data_wr_ptr_reg = 0;
|
reg [5:0] out_fifo_data_wr_ptr_reg = 0;
|
||||||
@ -888,8 +923,8 @@ generate
|
|||||||
reg [5:0] out_fifo_ctrl_wr_ptr_reg = 0;
|
reg [5:0] out_fifo_ctrl_wr_ptr_reg = 0;
|
||||||
reg [KEEP_WIDTH-1:0] out_fifo_ctrl_wr_tkeep;
|
reg [KEEP_WIDTH-1:0] out_fifo_ctrl_wr_tkeep;
|
||||||
reg out_fifo_ctrl_wr_tlast;
|
reg out_fifo_ctrl_wr_tlast;
|
||||||
reg [ID_WIDTH-1:0] out_fifo_ctrl_wr_tid;
|
reg [M_ID_WIDTH-1:0] out_fifo_ctrl_wr_tid;
|
||||||
reg [DEST_WIDTH-1:0] out_fifo_ctrl_wr_tdest;
|
reg [M_DEST_WIDTH-1:0] out_fifo_ctrl_wr_tdest;
|
||||||
reg [USER_WIDTH-1:0] out_fifo_ctrl_wr_tuser;
|
reg [USER_WIDTH-1:0] out_fifo_ctrl_wr_tuser;
|
||||||
reg out_fifo_ctrl_wr_en;
|
reg out_fifo_ctrl_wr_en;
|
||||||
reg [5:0] out_fifo_rd_ptr_reg = 0;
|
reg [5:0] out_fifo_rd_ptr_reg = 0;
|
||||||
@ -1071,9 +1106,9 @@ generate
|
|||||||
.M_KEEP_ENABLE(M_KEEP_ENABLE),
|
.M_KEEP_ENABLE(M_KEEP_ENABLE),
|
||||||
.M_KEEP_WIDTH(M_KEEP_WIDTH),
|
.M_KEEP_WIDTH(M_KEEP_WIDTH),
|
||||||
.ID_ENABLE(ID_ENABLE),
|
.ID_ENABLE(ID_ENABLE),
|
||||||
.ID_WIDTH(ID_WIDTH),
|
.ID_WIDTH(M_ID_WIDTH),
|
||||||
.DEST_ENABLE(1),
|
.DEST_ENABLE(M_DEST_WIDTH > 0),
|
||||||
.DEST_WIDTH(DEST_WIDTH),
|
.DEST_WIDTH(M_DEST_WIDTH_INT),
|
||||||
.USER_ENABLE(USER_ENABLE),
|
.USER_ENABLE(USER_ENABLE),
|
||||||
.USER_WIDTH(USER_WIDTH)
|
.USER_WIDTH(USER_WIDTH)
|
||||||
)
|
)
|
||||||
@ -1095,8 +1130,8 @@ generate
|
|||||||
.m_axis_tvalid(m_axis_tvalid[n]),
|
.m_axis_tvalid(m_axis_tvalid[n]),
|
||||||
.m_axis_tready(m_axis_tready[n]),
|
.m_axis_tready(m_axis_tready[n]),
|
||||||
.m_axis_tlast(m_axis_tlast[n]),
|
.m_axis_tlast(m_axis_tlast[n]),
|
||||||
.m_axis_tid(m_axis_tid[ID_WIDTH*n +: ID_WIDTH]),
|
.m_axis_tid(m_axis_tid[M_ID_WIDTH*n +: M_ID_WIDTH]),
|
||||||
.m_axis_tdest(m_axis_tdest[DEST_WIDTH*n +: DEST_WIDTH]),
|
.m_axis_tdest(m_axis_tdest[M_DEST_WIDTH*n +: M_DEST_WIDTH_INT]),
|
||||||
.m_axis_tuser(m_axis_tuser[USER_WIDTH*n +: USER_WIDTH])
|
.m_axis_tuser(m_axis_tuser[USER_WIDTH*n +: USER_WIDTH])
|
||||||
);
|
);
|
||||||
end // m_ifaces
|
end // m_ifaces
|
||||||
|
@ -100,11 +100,15 @@ module {{name}} #
|
|||||||
parameter M_KEEP_WIDTH = (M_DATA_WIDTH/8),
|
parameter M_KEEP_WIDTH = (M_DATA_WIDTH/8),
|
||||||
// Propagate tid signal
|
// Propagate tid signal
|
||||||
parameter ID_ENABLE = 0,
|
parameter ID_ENABLE = 0,
|
||||||
// tid signal width
|
// input tid signal width
|
||||||
parameter ID_WIDTH = 8,
|
parameter S_ID_WIDTH = 8,
|
||||||
// tdest signal width
|
// output tid signal width
|
||||||
|
parameter M_ID_WIDTH = S_ID_WIDTH+{{cm}},
|
||||||
|
// output tdest signal width
|
||||||
|
parameter M_DEST_WIDTH = 1,
|
||||||
|
// input tdest signal width
|
||||||
// must be wide enough to uniquely address outputs
|
// must be wide enough to uniquely address outputs
|
||||||
parameter DEST_WIDTH = {{cn}},
|
parameter S_DEST_WIDTH = M_DEST_WIDTH+{{cn}},
|
||||||
// Propagate tuser signal
|
// Propagate tuser signal
|
||||||
parameter USER_ENABLE = 1,
|
parameter USER_ENABLE = 1,
|
||||||
// tuser signal width
|
// tuser signal width
|
||||||
@ -128,6 +132,8 @@ module {{name}} #
|
|||||||
// Interface connection control
|
// Interface connection control
|
||||||
parameter M{{'%02d'%p}}_CONNECT = {{m}}'b{% for p in range(m) %}1{% endfor %},
|
parameter M{{'%02d'%p}}_CONNECT = {{m}}'b{% for p in range(m) %}1{% endfor %},
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
|
// Update tid with routing information
|
||||||
|
parameter UPDATE_TID = 0,
|
||||||
// select round robin arbitration
|
// select round robin arbitration
|
||||||
parameter ARB_TYPE_ROUND_ROBIN = 1,
|
parameter ARB_TYPE_ROUND_ROBIN = 1,
|
||||||
// LSB priority selection
|
// LSB priority selection
|
||||||
@ -143,27 +149,27 @@ module {{name}} #
|
|||||||
* AXI Stream inputs
|
* AXI Stream inputs
|
||||||
*/
|
*/
|
||||||
{%- for p in range(m) %}
|
{%- for p in range(m) %}
|
||||||
input wire [S_DATA_WIDTH-1:0] s{{'%02d'%p}}_axis_tdata,
|
input wire [S_DATA_WIDTH-1:0] s{{'%02d'%p}}_axis_tdata,
|
||||||
input wire [S_KEEP_WIDTH-1:0] s{{'%02d'%p}}_axis_tkeep,
|
input wire [S_KEEP_WIDTH-1:0] s{{'%02d'%p}}_axis_tkeep,
|
||||||
input wire s{{'%02d'%p}}_axis_tvalid,
|
input wire s{{'%02d'%p}}_axis_tvalid,
|
||||||
output wire s{{'%02d'%p}}_axis_tready,
|
output wire s{{'%02d'%p}}_axis_tready,
|
||||||
input wire s{{'%02d'%p}}_axis_tlast,
|
input wire s{{'%02d'%p}}_axis_tlast,
|
||||||
input wire [ID_WIDTH-1:0] s{{'%02d'%p}}_axis_tid,
|
input wire [S_ID_WIDTH-1:0] s{{'%02d'%p}}_axis_tid,
|
||||||
input wire [DEST_WIDTH-1:0] s{{'%02d'%p}}_axis_tdest,
|
input wire [S_DEST_WIDTH-1:0] s{{'%02d'%p}}_axis_tdest,
|
||||||
input wire [USER_WIDTH-1:0] s{{'%02d'%p}}_axis_tuser,
|
input wire [USER_WIDTH-1:0] s{{'%02d'%p}}_axis_tuser,
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
/*
|
/*
|
||||||
* AXI Stream outputs
|
* AXI Stream outputs
|
||||||
*/
|
*/
|
||||||
{%- for p in range(n) %}
|
{%- for p in range(n) %}
|
||||||
output wire [M_DATA_WIDTH-1:0] m{{'%02d'%p}}_axis_tdata,
|
output wire [M_DATA_WIDTH-1:0] m{{'%02d'%p}}_axis_tdata,
|
||||||
output wire [M_KEEP_WIDTH-1:0] m{{'%02d'%p}}_axis_tkeep,
|
output wire [M_KEEP_WIDTH-1:0] m{{'%02d'%p}}_axis_tkeep,
|
||||||
output wire m{{'%02d'%p}}_axis_tvalid,
|
output wire m{{'%02d'%p}}_axis_tvalid,
|
||||||
input wire m{{'%02d'%p}}_axis_tready,
|
input wire m{{'%02d'%p}}_axis_tready,
|
||||||
output wire m{{'%02d'%p}}_axis_tlast,
|
output wire m{{'%02d'%p}}_axis_tlast,
|
||||||
output wire [ID_WIDTH-1:0] m{{'%02d'%p}}_axis_tid,
|
output wire [M_ID_WIDTH-1:0] m{{'%02d'%p}}_axis_tid,
|
||||||
output wire [DEST_WIDTH-1:0] m{{'%02d'%p}}_axis_tdest,
|
output wire [M_DEST_WIDTH-1:0] m{{'%02d'%p}}_axis_tdest,
|
||||||
output wire [USER_WIDTH-1:0] m{{'%02d'%p}}_axis_tuser,
|
output wire [USER_WIDTH-1:0] m{{'%02d'%p}}_axis_tuser,
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
/*
|
/*
|
||||||
* Status
|
* Status
|
||||||
@ -174,7 +180,7 @@ module {{name}} #
|
|||||||
);
|
);
|
||||||
|
|
||||||
// parameter sizing helpers
|
// parameter sizing helpers
|
||||||
function [DEST_WIDTH-1:0] w_dw(input [DEST_WIDTH-1:0] val);
|
function [S_DEST_WIDTH-1:0] w_dw(input [S_DEST_WIDTH-1:0] val);
|
||||||
w_dw = val;
|
w_dw = val;
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
@ -195,8 +201,10 @@ axis_ram_switch #(
|
|||||||
.M_KEEP_ENABLE(M_KEEP_ENABLE),
|
.M_KEEP_ENABLE(M_KEEP_ENABLE),
|
||||||
.M_KEEP_WIDTH(M_KEEP_WIDTH),
|
.M_KEEP_WIDTH(M_KEEP_WIDTH),
|
||||||
.ID_ENABLE(ID_ENABLE),
|
.ID_ENABLE(ID_ENABLE),
|
||||||
.ID_WIDTH(ID_WIDTH),
|
.S_ID_WIDTH(S_ID_WIDTH),
|
||||||
.DEST_WIDTH(DEST_WIDTH),
|
.M_ID_WIDTH(M_ID_WIDTH),
|
||||||
|
.S_DEST_WIDTH(S_DEST_WIDTH),
|
||||||
|
.M_DEST_WIDTH(M_DEST_WIDTH),
|
||||||
.USER_ENABLE(USER_ENABLE),
|
.USER_ENABLE(USER_ENABLE),
|
||||||
.USER_WIDTH(USER_WIDTH),
|
.USER_WIDTH(USER_WIDTH),
|
||||||
.USER_BAD_FRAME_VALUE(USER_BAD_FRAME_VALUE),
|
.USER_BAD_FRAME_VALUE(USER_BAD_FRAME_VALUE),
|
||||||
@ -206,6 +214,7 @@ axis_ram_switch #(
|
|||||||
.M_BASE({ {% for p in range(n-1,-1,-1) %}w_dw(M{{'%02d'%p}}_BASE){% if not loop.last %}, {% endif %}{% endfor %} }),
|
.M_BASE({ {% for p in range(n-1,-1,-1) %}w_dw(M{{'%02d'%p}}_BASE){% if not loop.last %}, {% endif %}{% endfor %} }),
|
||||||
.M_TOP({ {% for p in range(n-1,-1,-1) %}w_dw(M{{'%02d'%p}}_TOP){% if not loop.last %}, {% endif %}{% endfor %} }),
|
.M_TOP({ {% for p in range(n-1,-1,-1) %}w_dw(M{{'%02d'%p}}_TOP){% if not loop.last %}, {% endif %}{% endfor %} }),
|
||||||
.M_CONNECT({ {% for p in range(n-1,-1,-1) %}w_s(M{{'%02d'%p}}_CONNECT){% if not loop.last %}, {% endif %}{% endfor %} }),
|
.M_CONNECT({ {% for p in range(n-1,-1,-1) %}w_s(M{{'%02d'%p}}_CONNECT){% if not loop.last %}, {% endif %}{% endfor %} }),
|
||||||
|
.UPDATE_TID(UPDATE_TID),
|
||||||
.ARB_TYPE_ROUND_ROBIN(ARB_TYPE_ROUND_ROBIN),
|
.ARB_TYPE_ROUND_ROBIN(ARB_TYPE_ROUND_ROBIN),
|
||||||
.ARB_LSB_HIGH_PRIORITY(ARB_LSB_HIGH_PRIORITY),
|
.ARB_LSB_HIGH_PRIORITY(ARB_LSB_HIGH_PRIORITY),
|
||||||
.RAM_PIPELINE(RAM_PIPELINE)
|
.RAM_PIPELINE(RAM_PIPELINE)
|
||||||
|
@ -45,28 +45,34 @@ module axis_switch #
|
|||||||
parameter KEEP_WIDTH = (DATA_WIDTH/8),
|
parameter KEEP_WIDTH = (DATA_WIDTH/8),
|
||||||
// Propagate tid signal
|
// Propagate tid signal
|
||||||
parameter ID_ENABLE = 0,
|
parameter ID_ENABLE = 0,
|
||||||
// tid signal width
|
// input tid signal width
|
||||||
parameter ID_WIDTH = 8,
|
parameter S_ID_WIDTH = 8,
|
||||||
// tdest signal width
|
// output tid signal width
|
||||||
|
parameter M_ID_WIDTH = S_ID_WIDTH+$clog2(S_COUNT),
|
||||||
|
// output tdest signal width
|
||||||
|
parameter M_DEST_WIDTH = 1,
|
||||||
|
// input tdest signal width
|
||||||
// must be wide enough to uniquely address outputs
|
// must be wide enough to uniquely address outputs
|
||||||
parameter DEST_WIDTH = $clog2(M_COUNT),
|
parameter S_DEST_WIDTH = M_DEST_WIDTH+$clog2(M_COUNT),
|
||||||
// Propagate tuser signal
|
// Propagate tuser signal
|
||||||
parameter USER_ENABLE = 1,
|
parameter USER_ENABLE = 1,
|
||||||
// tuser signal width
|
// tuser signal width
|
||||||
parameter USER_WIDTH = 1,
|
parameter USER_WIDTH = 1,
|
||||||
// Output interface routing base tdest selection
|
// Output interface routing base tdest selection
|
||||||
// Concatenate M_COUNT DEST_WIDTH sized constants
|
// Concatenate M_COUNT S_DEST_WIDTH sized constants
|
||||||
// Port selected if M_BASE <= tdest <= M_TOP
|
// Port selected if M_BASE <= tdest <= M_TOP
|
||||||
// set to zero for default routing with tdest MSBs as port index
|
// set to zero for default routing with tdest MSBs as port index
|
||||||
parameter M_BASE = 0,
|
parameter M_BASE = 0,
|
||||||
// Output interface routing top tdest selection
|
// Output interface routing top tdest selection
|
||||||
// Concatenate M_COUNT DEST_WIDTH sized constants
|
// Concatenate M_COUNT S_DEST_WIDTH sized constants
|
||||||
// Port selected if M_BASE <= tdest <= M_TOP
|
// Port selected if M_BASE <= tdest <= M_TOP
|
||||||
// set to zero to inherit from M_BASE
|
// set to zero to inherit from M_BASE
|
||||||
parameter M_TOP = 0,
|
parameter M_TOP = 0,
|
||||||
// Interface connection control
|
// Interface connection control
|
||||||
// M_COUNT concatenated fields of S_COUNT bits
|
// M_COUNT concatenated fields of S_COUNT bits
|
||||||
parameter M_CONNECT = {M_COUNT{{S_COUNT{1'b1}}}},
|
parameter M_CONNECT = {M_COUNT{{S_COUNT{1'b1}}}},
|
||||||
|
// Update tid with routing information
|
||||||
|
parameter UPDATE_TID = 0,
|
||||||
// Input interface register type
|
// Input interface register type
|
||||||
// 0 to bypass, 1 for simple buffer, 2 for skid buffer
|
// 0 to bypass, 1 for simple buffer, 2 for skid buffer
|
||||||
parameter S_REG_TYPE = 0,
|
parameter S_REG_TYPE = 0,
|
||||||
@ -79,65 +85,80 @@ module axis_switch #
|
|||||||
parameter ARB_LSB_HIGH_PRIORITY = 1
|
parameter ARB_LSB_HIGH_PRIORITY = 1
|
||||||
)
|
)
|
||||||
(
|
(
|
||||||
input wire clk,
|
input wire clk,
|
||||||
input wire rst,
|
input wire rst,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AXI Stream inputs
|
* AXI Stream inputs
|
||||||
*/
|
*/
|
||||||
input wire [S_COUNT*DATA_WIDTH-1:0] s_axis_tdata,
|
input wire [S_COUNT*DATA_WIDTH-1:0] s_axis_tdata,
|
||||||
input wire [S_COUNT*KEEP_WIDTH-1:0] s_axis_tkeep,
|
input wire [S_COUNT*KEEP_WIDTH-1:0] s_axis_tkeep,
|
||||||
input wire [S_COUNT-1:0] s_axis_tvalid,
|
input wire [S_COUNT-1:0] s_axis_tvalid,
|
||||||
output wire [S_COUNT-1:0] s_axis_tready,
|
output wire [S_COUNT-1:0] s_axis_tready,
|
||||||
input wire [S_COUNT-1:0] s_axis_tlast,
|
input wire [S_COUNT-1:0] s_axis_tlast,
|
||||||
input wire [S_COUNT*ID_WIDTH-1:0] s_axis_tid,
|
input wire [S_COUNT*S_ID_WIDTH-1:0] s_axis_tid,
|
||||||
input wire [S_COUNT*DEST_WIDTH-1:0] s_axis_tdest,
|
input wire [S_COUNT*S_DEST_WIDTH-1:0] s_axis_tdest,
|
||||||
input wire [S_COUNT*USER_WIDTH-1:0] s_axis_tuser,
|
input wire [S_COUNT*USER_WIDTH-1:0] s_axis_tuser,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AXI Stream outputs
|
* AXI Stream outputs
|
||||||
*/
|
*/
|
||||||
output wire [M_COUNT*DATA_WIDTH-1:0] m_axis_tdata,
|
output wire [M_COUNT*DATA_WIDTH-1:0] m_axis_tdata,
|
||||||
output wire [M_COUNT*KEEP_WIDTH-1:0] m_axis_tkeep,
|
output wire [M_COUNT*KEEP_WIDTH-1:0] m_axis_tkeep,
|
||||||
output wire [M_COUNT-1:0] m_axis_tvalid,
|
output wire [M_COUNT-1:0] m_axis_tvalid,
|
||||||
input wire [M_COUNT-1:0] m_axis_tready,
|
input wire [M_COUNT-1:0] m_axis_tready,
|
||||||
output wire [M_COUNT-1:0] m_axis_tlast,
|
output wire [M_COUNT-1:0] m_axis_tlast,
|
||||||
output wire [M_COUNT*ID_WIDTH-1:0] m_axis_tid,
|
output wire [M_COUNT*M_ID_WIDTH-1:0] m_axis_tid,
|
||||||
output wire [M_COUNT*DEST_WIDTH-1:0] m_axis_tdest,
|
output wire [M_COUNT*M_DEST_WIDTH-1:0] m_axis_tdest,
|
||||||
output wire [M_COUNT*USER_WIDTH-1:0] m_axis_tuser
|
output wire [M_COUNT*USER_WIDTH-1:0] m_axis_tuser
|
||||||
);
|
);
|
||||||
|
|
||||||
parameter CL_S_COUNT = $clog2(S_COUNT);
|
parameter CL_S_COUNT = $clog2(S_COUNT);
|
||||||
parameter CL_M_COUNT = $clog2(M_COUNT);
|
parameter CL_M_COUNT = $clog2(M_COUNT);
|
||||||
|
|
||||||
|
parameter S_ID_WIDTH_INT = S_ID_WIDTH > 0 ? S_ID_WIDTH : 1;
|
||||||
|
parameter M_DEST_WIDTH_INT = M_DEST_WIDTH > 0 ? M_DEST_WIDTH : 1;
|
||||||
|
|
||||||
integer i, j;
|
integer i, j;
|
||||||
|
|
||||||
// check configuration
|
// check configuration
|
||||||
initial begin
|
initial begin
|
||||||
if (DEST_WIDTH < CL_M_COUNT) begin
|
if (S_DEST_WIDTH < CL_M_COUNT) begin
|
||||||
$error("Error: DEST_WIDTH too small for port count (instance %m)");
|
$error("Error: S_DEST_WIDTH too small for port count (instance %m)");
|
||||||
$finish;
|
$finish;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if (UPDATE_TID) begin
|
||||||
|
if (!ID_ENABLE) begin
|
||||||
|
$error("Error: UPDATE_TID set requires ID_ENABLE set (instance %m)");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (M_ID_WIDTH < CL_S_COUNT) begin
|
||||||
|
$error("Error: M_ID_WIDTH too small for port count (instance %m)");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if (M_BASE == 0) begin
|
if (M_BASE == 0) begin
|
||||||
// M_BASE is zero, route with tdest as port index
|
// M_BASE is zero, route with tdest as port index
|
||||||
$display("Addressing configuration for axis_switch instance %m");
|
$display("Addressing configuration for axis_switch instance %m");
|
||||||
for (i = 0; i < M_COUNT; i = i + 1) begin
|
for (i = 0; i < M_COUNT; i = i + 1) begin
|
||||||
$display("%d: %08x-%08x (connect mask %b)", i, i << (DEST_WIDTH-CL_M_COUNT), ((i+1) << (DEST_WIDTH-CL_M_COUNT))-1, M_CONNECT[i*S_COUNT +: S_COUNT]);
|
$display("%d: %08x-%08x (connect mask %b)", i, i << (S_DEST_WIDTH-CL_M_COUNT), ((i+1) << (S_DEST_WIDTH-CL_M_COUNT))-1, M_CONNECT[i*S_COUNT +: S_COUNT]);
|
||||||
end
|
end
|
||||||
|
|
||||||
end else if (M_TOP == 0) begin
|
end else if (M_TOP == 0) begin
|
||||||
// M_TOP is zero, assume equal to M_BASE
|
// M_TOP is zero, assume equal to M_BASE
|
||||||
$display("Addressing configuration for axis_switch instance %m");
|
$display("Addressing configuration for axis_switch instance %m");
|
||||||
for (i = 0; i < M_COUNT; i = i + 1) begin
|
for (i = 0; i < M_COUNT; i = i + 1) begin
|
||||||
$display("%d: %08x (connect mask %b)", i, M_BASE[i*DEST_WIDTH +: DEST_WIDTH], M_CONNECT[i*S_COUNT +: S_COUNT]);
|
$display("%d: %08x (connect mask %b)", i, M_BASE[i*S_DEST_WIDTH +: S_DEST_WIDTH], M_CONNECT[i*S_COUNT +: S_COUNT]);
|
||||||
end
|
end
|
||||||
|
|
||||||
for (i = 0; i < M_COUNT; i = i + 1) begin
|
for (i = 0; i < M_COUNT; i = i + 1) begin
|
||||||
for (j = i+1; j < M_COUNT; j = j + 1) begin
|
for (j = i+1; j < M_COUNT; j = j + 1) begin
|
||||||
if (M_BASE[i*DEST_WIDTH +: DEST_WIDTH] == M_BASE[j*DEST_WIDTH +: DEST_WIDTH]) begin
|
if (M_BASE[i*S_DEST_WIDTH +: S_DEST_WIDTH] == M_BASE[j*S_DEST_WIDTH +: S_DEST_WIDTH]) begin
|
||||||
$display("%d: %08x", i, M_BASE[i*DEST_WIDTH +: DEST_WIDTH]);
|
$display("%d: %08x", i, M_BASE[i*S_DEST_WIDTH +: S_DEST_WIDTH]);
|
||||||
$display("%d: %08x", j, M_BASE[j*DEST_WIDTH +: DEST_WIDTH]);
|
$display("%d: %08x", j, M_BASE[j*S_DEST_WIDTH +: S_DEST_WIDTH]);
|
||||||
$error("Error: ranges overlap (instance %m)");
|
$error("Error: ranges overlap (instance %m)");
|
||||||
$finish;
|
$finish;
|
||||||
end
|
end
|
||||||
@ -146,11 +167,11 @@ initial begin
|
|||||||
end else begin
|
end else begin
|
||||||
$display("Addressing configuration for axis_switch instance %m");
|
$display("Addressing configuration for axis_switch instance %m");
|
||||||
for (i = 0; i < M_COUNT; i = i + 1) begin
|
for (i = 0; i < M_COUNT; i = i + 1) begin
|
||||||
$display("%d: %08x-%08x (connect mask %b)", i, M_BASE[i*DEST_WIDTH +: DEST_WIDTH], M_TOP[i*DEST_WIDTH +: DEST_WIDTH], M_CONNECT[i*S_COUNT +: S_COUNT]);
|
$display("%d: %08x-%08x (connect mask %b)", i, M_BASE[i*S_DEST_WIDTH +: S_DEST_WIDTH], M_TOP[i*S_DEST_WIDTH +: S_DEST_WIDTH], M_CONNECT[i*S_COUNT +: S_COUNT]);
|
||||||
end
|
end
|
||||||
|
|
||||||
for (i = 0; i < M_COUNT; i = i + 1) begin
|
for (i = 0; i < M_COUNT; i = i + 1) begin
|
||||||
if (M_BASE[i*DEST_WIDTH +: DEST_WIDTH] > M_TOP[i*DEST_WIDTH +: DEST_WIDTH]) begin
|
if (M_BASE[i*S_DEST_WIDTH +: S_DEST_WIDTH] > M_TOP[i*S_DEST_WIDTH +: S_DEST_WIDTH]) begin
|
||||||
$error("Error: invalid range (instance %m)");
|
$error("Error: invalid range (instance %m)");
|
||||||
$finish;
|
$finish;
|
||||||
end
|
end
|
||||||
@ -158,9 +179,9 @@ initial begin
|
|||||||
|
|
||||||
for (i = 0; i < M_COUNT; i = i + 1) begin
|
for (i = 0; i < M_COUNT; i = i + 1) begin
|
||||||
for (j = i+1; j < M_COUNT; j = j + 1) begin
|
for (j = i+1; j < M_COUNT; j = j + 1) begin
|
||||||
if (M_BASE[i*DEST_WIDTH +: DEST_WIDTH] <= M_TOP[j*DEST_WIDTH +: DEST_WIDTH] && M_BASE[j*DEST_WIDTH +: DEST_WIDTH] <= M_TOP[i*DEST_WIDTH +: DEST_WIDTH]) begin
|
if (M_BASE[i*S_DEST_WIDTH +: S_DEST_WIDTH] <= M_TOP[j*S_DEST_WIDTH +: S_DEST_WIDTH] && M_BASE[j*S_DEST_WIDTH +: S_DEST_WIDTH] <= M_TOP[i*S_DEST_WIDTH +: S_DEST_WIDTH]) begin
|
||||||
$display("%d: %08x-%08x", i, M_BASE[i*DEST_WIDTH +: DEST_WIDTH], M_TOP[i*DEST_WIDTH +: DEST_WIDTH]);
|
$display("%d: %08x-%08x", i, M_BASE[i*S_DEST_WIDTH +: S_DEST_WIDTH], M_TOP[i*S_DEST_WIDTH +: S_DEST_WIDTH]);
|
||||||
$display("%d: %08x-%08x", j, M_BASE[j*DEST_WIDTH +: DEST_WIDTH], M_TOP[j*DEST_WIDTH +: DEST_WIDTH]);
|
$display("%d: %08x-%08x", j, M_BASE[j*S_DEST_WIDTH +: S_DEST_WIDTH], M_TOP[j*S_DEST_WIDTH +: S_DEST_WIDTH]);
|
||||||
$error("Error: ranges overlap (instance %m)");
|
$error("Error: ranges overlap (instance %m)");
|
||||||
$finish;
|
$finish;
|
||||||
end
|
end
|
||||||
@ -169,17 +190,17 @@ initial begin
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
wire [S_COUNT*DATA_WIDTH-1:0] int_s_axis_tdata;
|
wire [S_COUNT*DATA_WIDTH-1:0] int_s_axis_tdata;
|
||||||
wire [S_COUNT*KEEP_WIDTH-1:0] int_s_axis_tkeep;
|
wire [S_COUNT*KEEP_WIDTH-1:0] int_s_axis_tkeep;
|
||||||
wire [S_COUNT-1:0] int_s_axis_tvalid;
|
wire [S_COUNT-1:0] int_s_axis_tvalid;
|
||||||
wire [S_COUNT-1:0] int_s_axis_tready;
|
wire [S_COUNT-1:0] int_s_axis_tready;
|
||||||
wire [S_COUNT-1:0] int_s_axis_tlast;
|
wire [S_COUNT-1:0] int_s_axis_tlast;
|
||||||
wire [S_COUNT*ID_WIDTH-1:0] int_s_axis_tid;
|
wire [S_COUNT*S_ID_WIDTH-1:0] int_s_axis_tid;
|
||||||
wire [S_COUNT*DEST_WIDTH-1:0] int_s_axis_tdest;
|
wire [S_COUNT*S_DEST_WIDTH-1:0] int_s_axis_tdest;
|
||||||
wire [S_COUNT*USER_WIDTH-1:0] int_s_axis_tuser;
|
wire [S_COUNT*USER_WIDTH-1:0] int_s_axis_tuser;
|
||||||
|
|
||||||
wire [S_COUNT*M_COUNT-1:0] int_axis_tvalid;
|
wire [S_COUNT*M_COUNT-1:0] int_axis_tvalid;
|
||||||
wire [M_COUNT*S_COUNT-1:0] int_axis_tready;
|
wire [M_COUNT*S_COUNT-1:0] int_axis_tready;
|
||||||
|
|
||||||
generate
|
generate
|
||||||
|
|
||||||
@ -212,7 +233,7 @@ generate
|
|||||||
drop_next = 1'b0;
|
drop_next = 1'b0;
|
||||||
end else begin
|
end else begin
|
||||||
// M_BASE is zero, route with $clog2(M_COUNT) MSBs of tdest as port index
|
// M_BASE is zero, route with $clog2(M_COUNT) MSBs of tdest as port index
|
||||||
if (int_s_axis_tdest[m*DEST_WIDTH+(DEST_WIDTH-CL_M_COUNT) +: CL_M_COUNT] == k && (M_CONNECT & (1 << (m+k*S_COUNT)))) begin
|
if (int_s_axis_tdest[m*S_DEST_WIDTH+(S_DEST_WIDTH-CL_M_COUNT) +: CL_M_COUNT] == k && (M_CONNECT & (1 << (m+k*S_COUNT)))) begin
|
||||||
select_next = k;
|
select_next = k;
|
||||||
select_valid_next = 1'b1;
|
select_valid_next = 1'b1;
|
||||||
drop_next = 1'b0;
|
drop_next = 1'b0;
|
||||||
@ -220,13 +241,13 @@ generate
|
|||||||
end
|
end
|
||||||
end else if (M_TOP == 0) begin
|
end else if (M_TOP == 0) begin
|
||||||
// M_TOP is zero, assume equal to M_BASE
|
// M_TOP is zero, assume equal to M_BASE
|
||||||
if (int_s_axis_tdest[m*DEST_WIDTH +: DEST_WIDTH] == M_BASE[k*DEST_WIDTH +: DEST_WIDTH] && (M_CONNECT & (1 << (m+k*S_COUNT)))) begin
|
if (int_s_axis_tdest[m*S_DEST_WIDTH +: S_DEST_WIDTH] == M_BASE[k*S_DEST_WIDTH +: S_DEST_WIDTH] && (M_CONNECT & (1 << (m+k*S_COUNT)))) begin
|
||||||
select_next = k;
|
select_next = k;
|
||||||
select_valid_next = 1'b1;
|
select_valid_next = 1'b1;
|
||||||
drop_next = 1'b0;
|
drop_next = 1'b0;
|
||||||
end
|
end
|
||||||
end else begin
|
end else begin
|
||||||
if (int_s_axis_tdest[m*DEST_WIDTH +: DEST_WIDTH] >= M_BASE[k*DEST_WIDTH +: DEST_WIDTH] && int_s_axis_tdest[m*DEST_WIDTH +: DEST_WIDTH] <= M_TOP[k*DEST_WIDTH +: DEST_WIDTH] && (M_CONNECT & (1 << (m+k*S_COUNT)))) begin
|
if (int_s_axis_tdest[m*S_DEST_WIDTH +: S_DEST_WIDTH] >= M_BASE[k*S_DEST_WIDTH +: S_DEST_WIDTH] && int_s_axis_tdest[m*S_DEST_WIDTH +: S_DEST_WIDTH] <= M_TOP[k*S_DEST_WIDTH +: S_DEST_WIDTH] && (M_CONNECT & (1 << (m+k*S_COUNT)))) begin
|
||||||
select_next = k;
|
select_next = k;
|
||||||
select_valid_next = 1'b1;
|
select_valid_next = 1'b1;
|
||||||
drop_next = 1'b0;
|
drop_next = 1'b0;
|
||||||
@ -257,10 +278,10 @@ generate
|
|||||||
.KEEP_ENABLE(KEEP_ENABLE),
|
.KEEP_ENABLE(KEEP_ENABLE),
|
||||||
.KEEP_WIDTH(KEEP_WIDTH),
|
.KEEP_WIDTH(KEEP_WIDTH),
|
||||||
.LAST_ENABLE(1),
|
.LAST_ENABLE(1),
|
||||||
.ID_ENABLE(ID_ENABLE),
|
.ID_ENABLE(ID_ENABLE && S_ID_WIDTH > 0),
|
||||||
.ID_WIDTH(ID_WIDTH),
|
.ID_WIDTH(S_ID_WIDTH_INT),
|
||||||
.DEST_ENABLE(1),
|
.DEST_ENABLE(1),
|
||||||
.DEST_WIDTH(DEST_WIDTH),
|
.DEST_WIDTH(S_DEST_WIDTH),
|
||||||
.USER_ENABLE(USER_ENABLE),
|
.USER_ENABLE(USER_ENABLE),
|
||||||
.USER_WIDTH(USER_WIDTH),
|
.USER_WIDTH(USER_WIDTH),
|
||||||
.REG_TYPE(S_REG_TYPE)
|
.REG_TYPE(S_REG_TYPE)
|
||||||
@ -274,8 +295,8 @@ generate
|
|||||||
.s_axis_tvalid(s_axis_tvalid[m]),
|
.s_axis_tvalid(s_axis_tvalid[m]),
|
||||||
.s_axis_tready(s_axis_tready[m]),
|
.s_axis_tready(s_axis_tready[m]),
|
||||||
.s_axis_tlast(s_axis_tlast[m]),
|
.s_axis_tlast(s_axis_tlast[m]),
|
||||||
.s_axis_tid(s_axis_tid[m*ID_WIDTH +: ID_WIDTH]),
|
.s_axis_tid(s_axis_tid[m*S_ID_WIDTH +: S_ID_WIDTH_INT]),
|
||||||
.s_axis_tdest(s_axis_tdest[m*DEST_WIDTH +: DEST_WIDTH]),
|
.s_axis_tdest(s_axis_tdest[m*S_DEST_WIDTH +: S_DEST_WIDTH]),
|
||||||
.s_axis_tuser(s_axis_tuser[m*USER_WIDTH +: USER_WIDTH]),
|
.s_axis_tuser(s_axis_tuser[m*USER_WIDTH +: USER_WIDTH]),
|
||||||
// AXI output
|
// AXI output
|
||||||
.m_axis_tdata(int_s_axis_tdata[m*DATA_WIDTH +: DATA_WIDTH]),
|
.m_axis_tdata(int_s_axis_tdata[m*DATA_WIDTH +: DATA_WIDTH]),
|
||||||
@ -283,8 +304,8 @@ generate
|
|||||||
.m_axis_tvalid(int_s_axis_tvalid[m]),
|
.m_axis_tvalid(int_s_axis_tvalid[m]),
|
||||||
.m_axis_tready(int_s_axis_tready[m]),
|
.m_axis_tready(int_s_axis_tready[m]),
|
||||||
.m_axis_tlast(int_s_axis_tlast[m]),
|
.m_axis_tlast(int_s_axis_tlast[m]),
|
||||||
.m_axis_tid(int_s_axis_tid[m*ID_WIDTH +: ID_WIDTH]),
|
.m_axis_tid(int_s_axis_tid[m*S_ID_WIDTH +: S_ID_WIDTH_INT]),
|
||||||
.m_axis_tdest(int_s_axis_tdest[m*DEST_WIDTH +: DEST_WIDTH]),
|
.m_axis_tdest(int_s_axis_tdest[m*S_DEST_WIDTH +: S_DEST_WIDTH]),
|
||||||
.m_axis_tuser(int_s_axis_tuser[m*USER_WIDTH +: USER_WIDTH])
|
.m_axis_tuser(int_s_axis_tuser[m*USER_WIDTH +: USER_WIDTH])
|
||||||
);
|
);
|
||||||
end // s_ifaces
|
end // s_ifaces
|
||||||
@ -316,20 +337,33 @@ generate
|
|||||||
);
|
);
|
||||||
|
|
||||||
// mux
|
// mux
|
||||||
wire [DATA_WIDTH-1:0] s_axis_tdata_mux = int_s_axis_tdata[grant_encoded*DATA_WIDTH +: DATA_WIDTH];
|
reg [DATA_WIDTH-1:0] m_axis_tdata_mux;
|
||||||
wire [KEEP_WIDTH-1:0] s_axis_tkeep_mux = int_s_axis_tkeep[grant_encoded*KEEP_WIDTH +: KEEP_WIDTH];
|
reg [KEEP_WIDTH-1:0] m_axis_tkeep_mux;
|
||||||
wire s_axis_tvalid_mux = int_axis_tvalid[grant_encoded*M_COUNT+n] && grant_valid;
|
reg m_axis_tvalid_mux;
|
||||||
wire s_axis_tready_mux;
|
wire m_axis_tready_mux;
|
||||||
wire s_axis_tlast_mux = int_s_axis_tlast[grant_encoded];
|
reg m_axis_tlast_mux;
|
||||||
wire [ID_WIDTH-1:0] s_axis_tid_mux = int_s_axis_tid[grant_encoded*ID_WIDTH +: ID_WIDTH];
|
reg [M_ID_WIDTH-1:0] m_axis_tid_mux;
|
||||||
wire [DEST_WIDTH-1:0] s_axis_tdest_mux = int_s_axis_tdest[grant_encoded*DEST_WIDTH +: DEST_WIDTH];
|
reg [M_DEST_WIDTH-1:0] m_axis_tdest_mux;
|
||||||
wire [USER_WIDTH-1:0] s_axis_tuser_mux = int_s_axis_tuser[grant_encoded*USER_WIDTH +: USER_WIDTH];
|
reg [USER_WIDTH-1:0] m_axis_tuser_mux;
|
||||||
|
|
||||||
assign int_axis_tready[n*S_COUNT +: S_COUNT] = (grant_valid && s_axis_tready_mux) << grant_encoded;
|
always @* begin
|
||||||
|
m_axis_tdata_mux = int_s_axis_tdata[grant_encoded*DATA_WIDTH +: DATA_WIDTH];
|
||||||
|
m_axis_tkeep_mux = int_s_axis_tkeep[grant_encoded*KEEP_WIDTH +: KEEP_WIDTH];
|
||||||
|
m_axis_tvalid_mux = int_axis_tvalid[grant_encoded*M_COUNT+n] && grant_valid;
|
||||||
|
m_axis_tlast_mux = int_s_axis_tlast[grant_encoded];
|
||||||
|
m_axis_tid_mux = int_s_axis_tid[grant_encoded*S_ID_WIDTH +: S_ID_WIDTH_INT];
|
||||||
|
if (UPDATE_TID && S_COUNT > 1) begin
|
||||||
|
m_axis_tid_mux[M_ID_WIDTH-1:M_ID_WIDTH-CL_S_COUNT] = grant_encoded;
|
||||||
|
end
|
||||||
|
m_axis_tdest_mux = int_s_axis_tdest[grant_encoded*S_DEST_WIDTH +: S_DEST_WIDTH];
|
||||||
|
m_axis_tuser_mux = int_s_axis_tuser[grant_encoded*USER_WIDTH +: USER_WIDTH];
|
||||||
|
end
|
||||||
|
|
||||||
|
assign int_axis_tready[n*S_COUNT +: S_COUNT] = (grant_valid && m_axis_tready_mux) << grant_encoded;
|
||||||
|
|
||||||
for (m = 0; m < S_COUNT; m = m + 1) begin
|
for (m = 0; m < S_COUNT; m = m + 1) begin
|
||||||
assign request[m] = int_axis_tvalid[m*M_COUNT+n] && !grant[m];
|
assign request[m] = int_axis_tvalid[m*M_COUNT+n] && !grant[m];
|
||||||
assign acknowledge[m] = grant[m] && int_axis_tvalid[m*M_COUNT+n] && s_axis_tlast_mux && s_axis_tready_mux;
|
assign acknowledge[m] = grant[m] && int_axis_tvalid[m*M_COUNT+n] && m_axis_tlast_mux && m_axis_tready_mux;
|
||||||
end
|
end
|
||||||
|
|
||||||
// M side register
|
// M side register
|
||||||
@ -339,9 +373,9 @@ generate
|
|||||||
.KEEP_WIDTH(KEEP_WIDTH),
|
.KEEP_WIDTH(KEEP_WIDTH),
|
||||||
.LAST_ENABLE(1),
|
.LAST_ENABLE(1),
|
||||||
.ID_ENABLE(ID_ENABLE),
|
.ID_ENABLE(ID_ENABLE),
|
||||||
.ID_WIDTH(ID_WIDTH),
|
.ID_WIDTH(M_ID_WIDTH),
|
||||||
.DEST_ENABLE(1),
|
.DEST_ENABLE(M_DEST_WIDTH > 0),
|
||||||
.DEST_WIDTH(DEST_WIDTH),
|
.DEST_WIDTH(M_DEST_WIDTH_INT),
|
||||||
.USER_ENABLE(USER_ENABLE),
|
.USER_ENABLE(USER_ENABLE),
|
||||||
.USER_WIDTH(USER_WIDTH),
|
.USER_WIDTH(USER_WIDTH),
|
||||||
.REG_TYPE(M_REG_TYPE)
|
.REG_TYPE(M_REG_TYPE)
|
||||||
@ -350,22 +384,22 @@ generate
|
|||||||
.clk(clk),
|
.clk(clk),
|
||||||
.rst(rst),
|
.rst(rst),
|
||||||
// AXI input
|
// AXI input
|
||||||
.s_axis_tdata(s_axis_tdata_mux),
|
.s_axis_tdata(m_axis_tdata_mux),
|
||||||
.s_axis_tkeep(s_axis_tkeep_mux),
|
.s_axis_tkeep(m_axis_tkeep_mux),
|
||||||
.s_axis_tvalid(s_axis_tvalid_mux),
|
.s_axis_tvalid(m_axis_tvalid_mux),
|
||||||
.s_axis_tready(s_axis_tready_mux),
|
.s_axis_tready(m_axis_tready_mux),
|
||||||
.s_axis_tlast(s_axis_tlast_mux),
|
.s_axis_tlast(m_axis_tlast_mux),
|
||||||
.s_axis_tid(s_axis_tid_mux),
|
.s_axis_tid(m_axis_tid_mux),
|
||||||
.s_axis_tdest(s_axis_tdest_mux),
|
.s_axis_tdest(m_axis_tdest_mux),
|
||||||
.s_axis_tuser(s_axis_tuser_mux),
|
.s_axis_tuser(m_axis_tuser_mux),
|
||||||
// AXI output
|
// AXI output
|
||||||
.m_axis_tdata(m_axis_tdata[n*DATA_WIDTH +: DATA_WIDTH]),
|
.m_axis_tdata(m_axis_tdata[n*DATA_WIDTH +: DATA_WIDTH]),
|
||||||
.m_axis_tkeep(m_axis_tkeep[n*KEEP_WIDTH +: KEEP_WIDTH]),
|
.m_axis_tkeep(m_axis_tkeep[n*KEEP_WIDTH +: KEEP_WIDTH]),
|
||||||
.m_axis_tvalid(m_axis_tvalid[n]),
|
.m_axis_tvalid(m_axis_tvalid[n]),
|
||||||
.m_axis_tready(m_axis_tready[n]),
|
.m_axis_tready(m_axis_tready[n]),
|
||||||
.m_axis_tlast(m_axis_tlast[n]),
|
.m_axis_tlast(m_axis_tlast[n]),
|
||||||
.m_axis_tid(m_axis_tid[n*ID_WIDTH +: ID_WIDTH]),
|
.m_axis_tid(m_axis_tid[n*M_ID_WIDTH +: M_ID_WIDTH]),
|
||||||
.m_axis_tdest(m_axis_tdest[n*DEST_WIDTH +: DEST_WIDTH]),
|
.m_axis_tdest(m_axis_tdest[n*M_DEST_WIDTH +: M_DEST_WIDTH_INT]),
|
||||||
.m_axis_tuser(m_axis_tuser[n*USER_WIDTH +: USER_WIDTH])
|
.m_axis_tuser(m_axis_tuser[n*USER_WIDTH +: USER_WIDTH])
|
||||||
);
|
);
|
||||||
end // m_ifaces
|
end // m_ifaces
|
||||||
|
@ -84,11 +84,15 @@ module {{name}} #
|
|||||||
parameter KEEP_WIDTH = (DATA_WIDTH/8),
|
parameter KEEP_WIDTH = (DATA_WIDTH/8),
|
||||||
// Propagate tid signal
|
// Propagate tid signal
|
||||||
parameter ID_ENABLE = 0,
|
parameter ID_ENABLE = 0,
|
||||||
// tid signal width
|
// input tid signal width
|
||||||
parameter ID_WIDTH = 8,
|
parameter S_ID_WIDTH = 8,
|
||||||
// tdest signal width
|
// output tid signal width
|
||||||
|
parameter M_ID_WIDTH = S_ID_WIDTH+{{cm}},
|
||||||
|
// output tdest signal width
|
||||||
|
parameter M_DEST_WIDTH = 1,
|
||||||
|
// input tdest signal width
|
||||||
// must be wide enough to uniquely address outputs
|
// must be wide enough to uniquely address outputs
|
||||||
parameter DEST_WIDTH = {{cn}},
|
parameter S_DEST_WIDTH = M_DEST_WIDTH+{{cn}},
|
||||||
// Propagate tuser signal
|
// Propagate tuser signal
|
||||||
parameter USER_ENABLE = 1,
|
parameter USER_ENABLE = 1,
|
||||||
// tuser signal width
|
// tuser signal width
|
||||||
@ -103,6 +107,8 @@ module {{name}} #
|
|||||||
// Interface connection control
|
// Interface connection control
|
||||||
parameter M{{'%02d'%p}}_CONNECT = {{m}}'b{% for p in range(m) %}1{% endfor %},
|
parameter M{{'%02d'%p}}_CONNECT = {{m}}'b{% for p in range(m) %}1{% endfor %},
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
|
// Update tid with routing information
|
||||||
|
parameter UPDATE_TID = 0,
|
||||||
// Input interface register type
|
// Input interface register type
|
||||||
// 0 to bypass, 1 for simple buffer, 2 for skid buffer
|
// 0 to bypass, 1 for simple buffer, 2 for skid buffer
|
||||||
parameter S_REG_TYPE = 0,
|
parameter S_REG_TYPE = 0,
|
||||||
@ -122,32 +128,32 @@ module {{name}} #
|
|||||||
* AXI Stream inputs
|
* AXI Stream inputs
|
||||||
*/
|
*/
|
||||||
{%- for p in range(m) %}
|
{%- for p in range(m) %}
|
||||||
input wire [DATA_WIDTH-1:0] s{{'%02d'%p}}_axis_tdata,
|
input wire [DATA_WIDTH-1:0] s{{'%02d'%p}}_axis_tdata,
|
||||||
input wire [KEEP_WIDTH-1:0] s{{'%02d'%p}}_axis_tkeep,
|
input wire [KEEP_WIDTH-1:0] s{{'%02d'%p}}_axis_tkeep,
|
||||||
input wire s{{'%02d'%p}}_axis_tvalid,
|
input wire s{{'%02d'%p}}_axis_tvalid,
|
||||||
output wire s{{'%02d'%p}}_axis_tready,
|
output wire s{{'%02d'%p}}_axis_tready,
|
||||||
input wire s{{'%02d'%p}}_axis_tlast,
|
input wire s{{'%02d'%p}}_axis_tlast,
|
||||||
input wire [ID_WIDTH-1:0] s{{'%02d'%p}}_axis_tid,
|
input wire [S_ID_WIDTH-1:0] s{{'%02d'%p}}_axis_tid,
|
||||||
input wire [DEST_WIDTH-1:0] s{{'%02d'%p}}_axis_tdest,
|
input wire [S_DEST_WIDTH-1:0] s{{'%02d'%p}}_axis_tdest,
|
||||||
input wire [USER_WIDTH-1:0] s{{'%02d'%p}}_axis_tuser,
|
input wire [USER_WIDTH-1:0] s{{'%02d'%p}}_axis_tuser,
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
/*
|
/*
|
||||||
* AXI Stream outputs
|
* AXI Stream outputs
|
||||||
*/
|
*/
|
||||||
{%- for p in range(n) %}
|
{%- for p in range(n) %}
|
||||||
output wire [DATA_WIDTH-1:0] m{{'%02d'%p}}_axis_tdata,
|
output wire [DATA_WIDTH-1:0] m{{'%02d'%p}}_axis_tdata,
|
||||||
output wire [KEEP_WIDTH-1:0] m{{'%02d'%p}}_axis_tkeep,
|
output wire [KEEP_WIDTH-1:0] m{{'%02d'%p}}_axis_tkeep,
|
||||||
output wire m{{'%02d'%p}}_axis_tvalid,
|
output wire m{{'%02d'%p}}_axis_tvalid,
|
||||||
input wire m{{'%02d'%p}}_axis_tready,
|
input wire m{{'%02d'%p}}_axis_tready,
|
||||||
output wire m{{'%02d'%p}}_axis_tlast,
|
output wire m{{'%02d'%p}}_axis_tlast,
|
||||||
output wire [ID_WIDTH-1:0] m{{'%02d'%p}}_axis_tid,
|
output wire [M_ID_WIDTH-1:0] m{{'%02d'%p}}_axis_tid,
|
||||||
output wire [DEST_WIDTH-1:0] m{{'%02d'%p}}_axis_tdest,
|
output wire [M_DEST_WIDTH-1:0] m{{'%02d'%p}}_axis_tdest,
|
||||||
output wire [USER_WIDTH-1:0] m{{'%02d'%p}}_axis_tuser{% if not loop.last %},{% endif %}
|
output wire [USER_WIDTH-1:0] m{{'%02d'%p}}_axis_tuser{% if not loop.last %},{% endif %}
|
||||||
{% endfor -%}
|
{% endfor -%}
|
||||||
);
|
);
|
||||||
|
|
||||||
// parameter sizing helpers
|
// parameter sizing helpers
|
||||||
function [DEST_WIDTH-1:0] w_dw(input [DEST_WIDTH-1:0] val);
|
function [S_DEST_WIDTH-1:0] w_dw(input [S_DEST_WIDTH-1:0] val);
|
||||||
w_dw = val;
|
w_dw = val;
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
@ -162,13 +168,16 @@ axis_switch #(
|
|||||||
.KEEP_ENABLE(KEEP_ENABLE),
|
.KEEP_ENABLE(KEEP_ENABLE),
|
||||||
.KEEP_WIDTH(KEEP_WIDTH),
|
.KEEP_WIDTH(KEEP_WIDTH),
|
||||||
.ID_ENABLE(ID_ENABLE),
|
.ID_ENABLE(ID_ENABLE),
|
||||||
.ID_WIDTH(ID_WIDTH),
|
.S_ID_WIDTH(S_ID_WIDTH),
|
||||||
.DEST_WIDTH(DEST_WIDTH),
|
.M_ID_WIDTH(M_ID_WIDTH),
|
||||||
|
.S_DEST_WIDTH(S_DEST_WIDTH),
|
||||||
|
.M_DEST_WIDTH(M_DEST_WIDTH),
|
||||||
.USER_ENABLE(USER_ENABLE),
|
.USER_ENABLE(USER_ENABLE),
|
||||||
.USER_WIDTH(USER_WIDTH),
|
.USER_WIDTH(USER_WIDTH),
|
||||||
.M_BASE({ {% for p in range(n-1,-1,-1) %}w_dw(M{{'%02d'%p}}_BASE){% if not loop.last %}, {% endif %}{% endfor %} }),
|
.M_BASE({ {% for p in range(n-1,-1,-1) %}w_dw(M{{'%02d'%p}}_BASE){% if not loop.last %}, {% endif %}{% endfor %} }),
|
||||||
.M_TOP({ {% for p in range(n-1,-1,-1) %}w_dw(M{{'%02d'%p}}_TOP){% if not loop.last %}, {% endif %}{% endfor %} }),
|
.M_TOP({ {% for p in range(n-1,-1,-1) %}w_dw(M{{'%02d'%p}}_TOP){% if not loop.last %}, {% endif %}{% endfor %} }),
|
||||||
.M_CONNECT({ {% for p in range(n-1,-1,-1) %}w_s(M{{'%02d'%p}}_CONNECT){% if not loop.last %}, {% endif %}{% endfor %} }),
|
.M_CONNECT({ {% for p in range(n-1,-1,-1) %}w_s(M{{'%02d'%p}}_CONNECT){% if not loop.last %}, {% endif %}{% endfor %} }),
|
||||||
|
.UPDATE_TID(UPDATE_TID),
|
||||||
.S_REG_TYPE(S_REG_TYPE),
|
.S_REG_TYPE(S_REG_TYPE),
|
||||||
.M_REG_TYPE(M_REG_TYPE),
|
.M_REG_TYPE(M_REG_TYPE),
|
||||||
.ARB_TYPE_ROUND_ROBIN(ARB_TYPE_ROUND_ROBIN),
|
.ARB_TYPE_ROUND_ROBIN(ARB_TYPE_ROUND_ROBIN),
|
||||||
|
@ -63,10 +63,10 @@ class TB(object):
|
|||||||
self.dut.rst.setimmediatevalue(0)
|
self.dut.rst.setimmediatevalue(0)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
self.dut.rst <= 1
|
self.dut.rst.value = 1
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
self.dut.rst <= 0
|
self.dut.rst.value = 0
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
|
|
||||||
|
@ -26,10 +26,10 @@ WAVES ?= 0
|
|||||||
COCOTB_HDL_TIMEUNIT = 1ns
|
COCOTB_HDL_TIMEUNIT = 1ns
|
||||||
COCOTB_HDL_TIMEPRECISION = 1ps
|
COCOTB_HDL_TIMEPRECISION = 1ps
|
||||||
|
|
||||||
export PARAM_PORTS ?= 4
|
export PORTS ?= 4
|
||||||
|
|
||||||
DUT = axis_arb_mux
|
DUT = axis_arb_mux
|
||||||
WRAPPER = $(DUT)_wrap_$(PARAM_PORTS)
|
WRAPPER = $(DUT)_wrap_$(PORTS)
|
||||||
TOPLEVEL = $(WRAPPER)
|
TOPLEVEL = $(WRAPPER)
|
||||||
MODULE = test_$(DUT)
|
MODULE = test_$(DUT)
|
||||||
VERILOG_SOURCES += $(WRAPPER).v
|
VERILOG_SOURCES += $(WRAPPER).v
|
||||||
@ -42,12 +42,14 @@ export PARAM_DATA_WIDTH ?= 8
|
|||||||
export PARAM_KEEP_ENABLE ?= $(shell expr $(PARAM_DATA_WIDTH) \> 8 )
|
export PARAM_KEEP_ENABLE ?= $(shell expr $(PARAM_DATA_WIDTH) \> 8 )
|
||||||
export PARAM_KEEP_WIDTH ?= $(shell expr $(PARAM_DATA_WIDTH) / 8 )
|
export PARAM_KEEP_WIDTH ?= $(shell expr $(PARAM_DATA_WIDTH) / 8 )
|
||||||
export PARAM_ID_ENABLE ?= 1
|
export PARAM_ID_ENABLE ?= 1
|
||||||
export PARAM_ID_WIDTH ?= 8
|
export PARAM_S_ID_WIDTH ?= 8
|
||||||
|
export PARAM_M_ID_WIDTH ?= $(shell python -c "print($(PARAM_S_ID_WIDTH) + ($(PORTS)-1).bit_length())")
|
||||||
export PARAM_DEST_ENABLE ?= 1
|
export PARAM_DEST_ENABLE ?= 1
|
||||||
export PARAM_DEST_WIDTH ?= 8
|
export PARAM_DEST_WIDTH ?= 8
|
||||||
export PARAM_USER_ENABLE ?= 1
|
export PARAM_USER_ENABLE ?= 1
|
||||||
export PARAM_USER_WIDTH ?= 1
|
export PARAM_USER_WIDTH ?= 1
|
||||||
export PARAM_LAST_ENABLE ?= 1
|
export PARAM_LAST_ENABLE ?= 1
|
||||||
|
export PARAM_UPDATE_TID ?= 1
|
||||||
export PARAM_ARB_TYPE_ROUND_ROBIN ?= 0
|
export PARAM_ARB_TYPE_ROUND_ROBIN ?= 0
|
||||||
export PARAM_ARB_LSB_HIGH_PRIORITY ?= 1
|
export PARAM_ARB_LSB_HIGH_PRIORITY ?= 1
|
||||||
|
|
||||||
@ -58,12 +60,14 @@ ifeq ($(SIM), icarus)
|
|||||||
COMPILE_ARGS += -P $(TOPLEVEL).KEEP_ENABLE=$(PARAM_KEEP_ENABLE)
|
COMPILE_ARGS += -P $(TOPLEVEL).KEEP_ENABLE=$(PARAM_KEEP_ENABLE)
|
||||||
COMPILE_ARGS += -P $(TOPLEVEL).KEEP_WIDTH=$(PARAM_KEEP_WIDTH)
|
COMPILE_ARGS += -P $(TOPLEVEL).KEEP_WIDTH=$(PARAM_KEEP_WIDTH)
|
||||||
COMPILE_ARGS += -P $(TOPLEVEL).ID_ENABLE=$(PARAM_ID_ENABLE)
|
COMPILE_ARGS += -P $(TOPLEVEL).ID_ENABLE=$(PARAM_ID_ENABLE)
|
||||||
COMPILE_ARGS += -P $(TOPLEVEL).ID_WIDTH=$(PARAM_ID_WIDTH)
|
COMPILE_ARGS += -P $(TOPLEVEL).M_ID_WIDTH=$(PARAM_M_ID_WIDTH)
|
||||||
|
COMPILE_ARGS += -P $(TOPLEVEL).S_ID_WIDTH=$(PARAM_S_ID_WIDTH)
|
||||||
COMPILE_ARGS += -P $(TOPLEVEL).DEST_ENABLE=$(PARAM_DEST_ENABLE)
|
COMPILE_ARGS += -P $(TOPLEVEL).DEST_ENABLE=$(PARAM_DEST_ENABLE)
|
||||||
COMPILE_ARGS += -P $(TOPLEVEL).DEST_WIDTH=$(PARAM_DEST_WIDTH)
|
COMPILE_ARGS += -P $(TOPLEVEL).DEST_WIDTH=$(PARAM_DEST_WIDTH)
|
||||||
COMPILE_ARGS += -P $(TOPLEVEL).USER_ENABLE=$(PARAM_USER_ENABLE)
|
COMPILE_ARGS += -P $(TOPLEVEL).USER_ENABLE=$(PARAM_USER_ENABLE)
|
||||||
COMPILE_ARGS += -P $(TOPLEVEL).USER_WIDTH=$(PARAM_USER_WIDTH)
|
COMPILE_ARGS += -P $(TOPLEVEL).USER_WIDTH=$(PARAM_USER_WIDTH)
|
||||||
COMPILE_ARGS += -P $(TOPLEVEL).LAST_ENABLE=$(PARAM_LAST_ENABLE)
|
COMPILE_ARGS += -P $(TOPLEVEL).LAST_ENABLE=$(PARAM_LAST_ENABLE)
|
||||||
|
COMPILE_ARGS += -P $(TOPLEVEL).UPDATE_TID=$(PARAM_UPDATE_TID)
|
||||||
COMPILE_ARGS += -P $(TOPLEVEL).ARB_TYPE_ROUND_ROBIN=$(PARAM_ARB_TYPE_ROUND_ROBIN)
|
COMPILE_ARGS += -P $(TOPLEVEL).ARB_TYPE_ROUND_ROBIN=$(PARAM_ARB_TYPE_ROUND_ROBIN)
|
||||||
COMPILE_ARGS += -P $(TOPLEVEL).ARB_LSB_HIGH_PRIORITY=$(PARAM_ARB_LSB_HIGH_PRIORITY)
|
COMPILE_ARGS += -P $(TOPLEVEL).ARB_LSB_HIGH_PRIORITY=$(PARAM_ARB_LSB_HIGH_PRIORITY)
|
||||||
|
|
||||||
@ -78,12 +82,14 @@ else ifeq ($(SIM), verilator)
|
|||||||
COMPILE_ARGS += -GKEEP_ENABLE=$(PARAM_KEEP_ENABLE)
|
COMPILE_ARGS += -GKEEP_ENABLE=$(PARAM_KEEP_ENABLE)
|
||||||
COMPILE_ARGS += -GKEEP_WIDTH=$(PARAM_KEEP_WIDTH)
|
COMPILE_ARGS += -GKEEP_WIDTH=$(PARAM_KEEP_WIDTH)
|
||||||
COMPILE_ARGS += -GID_ENABLE=$(PARAM_ID_ENABLE)
|
COMPILE_ARGS += -GID_ENABLE=$(PARAM_ID_ENABLE)
|
||||||
COMPILE_ARGS += -GID_WIDTH=$(PARAM_ID_WIDTH)
|
COMPILE_ARGS += -GM_ID_WIDTH=$(PARAM_M_ID_WIDTH)
|
||||||
|
COMPILE_ARGS += -GS_ID_WIDTH=$(PARAM_S_ID_WIDTH)
|
||||||
COMPILE_ARGS += -GDEST_ENABLE=$(PARAM_DEST_ENABLE)
|
COMPILE_ARGS += -GDEST_ENABLE=$(PARAM_DEST_ENABLE)
|
||||||
COMPILE_ARGS += -GDEST_WIDTH=$(PARAM_DEST_WIDTH)
|
COMPILE_ARGS += -GDEST_WIDTH=$(PARAM_DEST_WIDTH)
|
||||||
COMPILE_ARGS += -GUSER_ENABLE=$(PARAM_USER_ENABLE)
|
COMPILE_ARGS += -GUSER_ENABLE=$(PARAM_USER_ENABLE)
|
||||||
COMPILE_ARGS += -GUSER_WIDTH=$(PARAM_USER_WIDTH)
|
COMPILE_ARGS += -GUSER_WIDTH=$(PARAM_USER_WIDTH)
|
||||||
COMPILE_ARGS += -GLAST_ENABLE=$(PARAM_LAST_ENABLE)
|
COMPILE_ARGS += -GLAST_ENABLE=$(PARAM_LAST_ENABLE)
|
||||||
|
COMPILE_ARGS += -GUPDATE_TID=$(PARAM_UPDATE_TID)
|
||||||
COMPILE_ARGS += -GARB_TYPE_ROUND_ROBIN=$(PARAM_ARB_TYPE_ROUND_ROBIN)
|
COMPILE_ARGS += -GARB_TYPE_ROUND_ROBIN=$(PARAM_ARB_TYPE_ROUND_ROBIN)
|
||||||
COMPILE_ARGS += -GARB_LSB_HIGH_PRIORITY=$(PARAM_ARB_LSB_HIGH_PRIORITY)
|
COMPILE_ARGS += -GARB_LSB_HIGH_PRIORITY=$(PARAM_ARB_LSB_HIGH_PRIORITY)
|
||||||
|
|
||||||
@ -95,7 +101,7 @@ endif
|
|||||||
include $(shell cocotb-config --makefiles)/Makefile.sim
|
include $(shell cocotb-config --makefiles)/Makefile.sim
|
||||||
|
|
||||||
$(WRAPPER).v: ../../rtl/$(DUT)_wrap.py
|
$(WRAPPER).v: ../../rtl/$(DUT)_wrap.py
|
||||||
$< -p $(PARAM_PORTS)
|
$< -p $(PORTS)
|
||||||
|
|
||||||
iverilog_dump.v:
|
iverilog_dump.v:
|
||||||
echo 'module iverilog_dump();' > $@
|
echo 'module iverilog_dump();' > $@
|
||||||
|
@ -67,10 +67,10 @@ class TB(object):
|
|||||||
self.dut.rst.setimmediatevalue(0)
|
self.dut.rst.setimmediatevalue(0)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
self.dut.rst <= 1
|
self.dut.rst.value = 1
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
self.dut.rst <= 0
|
self.dut.rst.value = 0
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
|
|
||||||
@ -79,7 +79,15 @@ async def run_test(dut, payload_lengths=None, payload_data=None, idle_inserter=N
|
|||||||
|
|
||||||
tb = TB(dut)
|
tb = TB(dut)
|
||||||
|
|
||||||
id_count = 2**len(tb.source[port].bus.tid)
|
id_width = len(tb.source[0].bus.tid)
|
||||||
|
id_count = 2**id_width
|
||||||
|
id_mask = id_count-1
|
||||||
|
|
||||||
|
src_width = (len(tb.source)-1).bit_length()
|
||||||
|
src_mask = 2**src_width-1 if src_width else 0
|
||||||
|
src_shift = id_width-src_width
|
||||||
|
max_count = 2**src_shift
|
||||||
|
count_mask = max_count-1
|
||||||
|
|
||||||
cur_id = 1
|
cur_id = 1
|
||||||
|
|
||||||
@ -92,19 +100,21 @@ async def run_test(dut, payload_lengths=None, payload_data=None, idle_inserter=N
|
|||||||
|
|
||||||
for test_data in [payload_data(x) for x in payload_lengths()]:
|
for test_data in [payload_data(x) for x in payload_lengths()]:
|
||||||
test_frame = AxiStreamFrame(test_data)
|
test_frame = AxiStreamFrame(test_data)
|
||||||
test_frame.tid = cur_id
|
test_frame.tid = cur_id | (port << src_shift)
|
||||||
test_frame.tdest = cur_id
|
test_frame.tdest = cur_id
|
||||||
|
|
||||||
test_frames.append(test_frame)
|
test_frames.append(test_frame)
|
||||||
await tb.source[port].send(test_frame)
|
await tb.source[port].send(test_frame)
|
||||||
|
|
||||||
cur_id = (cur_id + 1) % id_count
|
cur_id = (cur_id + 1) % max_count
|
||||||
|
|
||||||
for test_frame in test_frames:
|
for test_frame in test_frames:
|
||||||
rx_frame = await tb.sink.recv()
|
rx_frame = await tb.sink.recv()
|
||||||
|
|
||||||
assert rx_frame.tdata == test_frame.tdata
|
assert rx_frame.tdata == test_frame.tdata
|
||||||
assert rx_frame.tid == test_frame.tid
|
assert (rx_frame.tid & id_mask) == test_frame.tid
|
||||||
|
assert ((rx_frame.tid >> src_shift) & src_mask) == port
|
||||||
|
assert (rx_frame.tid >> id_width) == port
|
||||||
assert rx_frame.tdest == test_frame.tdest
|
assert rx_frame.tdest == test_frame.tdest
|
||||||
assert not rx_frame.tuser
|
assert not rx_frame.tuser
|
||||||
|
|
||||||
@ -140,7 +150,15 @@ async def run_arb_test(dut):
|
|||||||
tb = TB(dut)
|
tb = TB(dut)
|
||||||
|
|
||||||
byte_lanes = tb.source[0].byte_lanes
|
byte_lanes = tb.source[0].byte_lanes
|
||||||
id_count = 2**len(tb.source[0].bus.tid)
|
id_width = len(tb.source[0].bus.tid)
|
||||||
|
id_count = 2**id_width
|
||||||
|
id_mask = id_count-1
|
||||||
|
|
||||||
|
src_width = (len(tb.source)-1).bit_length()
|
||||||
|
src_mask = 2**src_width-1 if src_width else 0
|
||||||
|
src_shift = id_width-src_width
|
||||||
|
max_count = 2**src_shift
|
||||||
|
count_mask = max_count-1
|
||||||
|
|
||||||
cur_id = 1
|
cur_id = 1
|
||||||
|
|
||||||
@ -153,29 +171,34 @@ async def run_arb_test(dut):
|
|||||||
|
|
||||||
for k in range(5):
|
for k in range(5):
|
||||||
test_frame = AxiStreamFrame(test_data, tx_complete=Event())
|
test_frame = AxiStreamFrame(test_data, tx_complete=Event())
|
||||||
test_frame.tid = cur_id
|
|
||||||
|
src_ind = 0
|
||||||
|
|
||||||
if k == 0:
|
if k == 0:
|
||||||
test_frame.tdest = 0
|
src_ind = 0
|
||||||
elif k == 4:
|
elif k == 4:
|
||||||
await test_frames[1].tx_complete.wait()
|
await test_frames[1].tx_complete.wait()
|
||||||
for j in range(8):
|
for j in range(8):
|
||||||
await RisingEdge(dut.clk)
|
await RisingEdge(dut.clk)
|
||||||
test_frame.tdest = 0
|
src_ind = 0
|
||||||
else:
|
else:
|
||||||
test_frame.tdest = 1
|
src_ind = 1
|
||||||
|
|
||||||
|
test_frame.tid = cur_id | (src_ind << src_shift)
|
||||||
|
test_frame.tdest = 0
|
||||||
|
|
||||||
test_frames.append(test_frame)
|
test_frames.append(test_frame)
|
||||||
await tb.source[test_frame.tdest].send(test_frame)
|
await tb.source[src_ind].send(test_frame)
|
||||||
|
|
||||||
cur_id = (cur_id + 1) % id_count
|
cur_id = (cur_id + 1) % max_count
|
||||||
|
|
||||||
for k in [0, 1, 2, 4, 3]:
|
for k in [0, 1, 2, 4, 3]:
|
||||||
test_frame = test_frames[k]
|
test_frame = test_frames[k]
|
||||||
rx_frame = await tb.sink.recv()
|
rx_frame = await tb.sink.recv()
|
||||||
|
|
||||||
assert rx_frame.tdata == test_frame.tdata
|
assert rx_frame.tdata == test_frame.tdata
|
||||||
assert rx_frame.tid == test_frame.tid
|
assert (rx_frame.tid & id_mask) == test_frame.tid
|
||||||
|
assert ((rx_frame.tid >> src_shift) & src_mask) == (rx_frame.tid >> id_width)
|
||||||
assert rx_frame.tdest == test_frame.tdest
|
assert rx_frame.tdest == test_frame.tdest
|
||||||
assert not rx_frame.tuser
|
assert not rx_frame.tuser
|
||||||
|
|
||||||
@ -190,7 +213,15 @@ async def run_stress_test(dut, idle_inserter=None, backpressure_inserter=None):
|
|||||||
tb = TB(dut)
|
tb = TB(dut)
|
||||||
|
|
||||||
byte_lanes = tb.source[0].byte_lanes
|
byte_lanes = tb.source[0].byte_lanes
|
||||||
id_count = 2**len(tb.source[0].bus.tid)
|
id_width = len(tb.source[0].bus.tid)
|
||||||
|
id_count = 2**id_width
|
||||||
|
id_mask = id_count-1
|
||||||
|
|
||||||
|
src_width = (len(tb.source)-1).bit_length()
|
||||||
|
src_mask = 2**src_width-1 if src_width else 0
|
||||||
|
src_shift = id_width-src_width
|
||||||
|
max_count = 2**src_shift
|
||||||
|
count_mask = max_count-1
|
||||||
|
|
||||||
cur_id = 1
|
cur_id = 1
|
||||||
|
|
||||||
@ -206,13 +237,13 @@ async def run_stress_test(dut, idle_inserter=None, backpressure_inserter=None):
|
|||||||
length = random.randint(1, byte_lanes*16)
|
length = random.randint(1, byte_lanes*16)
|
||||||
test_data = bytearray(itertools.islice(itertools.cycle(range(256)), length))
|
test_data = bytearray(itertools.islice(itertools.cycle(range(256)), length))
|
||||||
test_frame = AxiStreamFrame(test_data)
|
test_frame = AxiStreamFrame(test_data)
|
||||||
test_frame.tid = p
|
test_frame.tid = cur_id | (p << src_shift)
|
||||||
test_frame.tdest = cur_id
|
test_frame.tdest = cur_id
|
||||||
|
|
||||||
test_frames[p].append(test_frame)
|
test_frames[p].append(test_frame)
|
||||||
await tb.source[p].send(test_frame)
|
await tb.source[p].send(test_frame)
|
||||||
|
|
||||||
cur_id = (cur_id + 1) % id_count
|
cur_id = (cur_id + 1) % max_count
|
||||||
|
|
||||||
while any(test_frames):
|
while any(test_frames):
|
||||||
rx_frame = await tb.sink.recv()
|
rx_frame = await tb.sink.recv()
|
||||||
@ -220,14 +251,15 @@ async def run_stress_test(dut, idle_inserter=None, backpressure_inserter=None):
|
|||||||
test_frame = None
|
test_frame = None
|
||||||
|
|
||||||
for lst in test_frames:
|
for lst in test_frames:
|
||||||
if lst and lst[0].tid == rx_frame.tid:
|
if lst and lst[0].tid == (rx_frame.tid & id_mask):
|
||||||
test_frame = lst.pop(0)
|
test_frame = lst.pop(0)
|
||||||
break
|
break
|
||||||
|
|
||||||
assert test_frame is not None
|
assert test_frame is not None
|
||||||
|
|
||||||
assert rx_frame.tdata == test_frame.tdata
|
assert rx_frame.tdata == test_frame.tdata
|
||||||
assert rx_frame.tid == test_frame.tid
|
assert (rx_frame.tid & id_mask) == test_frame.tid
|
||||||
|
assert ((rx_frame.tid >> src_shift) & src_mask) == (rx_frame.tid >> id_width)
|
||||||
assert rx_frame.tdest == test_frame.tdest
|
assert rx_frame.tdest == test_frame.tdest
|
||||||
assert not rx_frame.tuser
|
assert not rx_frame.tuser
|
||||||
|
|
||||||
@ -310,23 +342,25 @@ def test_axis_arb_mux(request, ports, data_width, round_robin):
|
|||||||
|
|
||||||
parameters = {}
|
parameters = {}
|
||||||
|
|
||||||
parameters['PORTS'] = ports
|
|
||||||
|
|
||||||
parameters['DATA_WIDTH'] = data_width
|
parameters['DATA_WIDTH'] = data_width
|
||||||
parameters['KEEP_ENABLE'] = int(parameters['DATA_WIDTH'] > 8)
|
parameters['KEEP_ENABLE'] = int(parameters['DATA_WIDTH'] > 8)
|
||||||
parameters['KEEP_WIDTH'] = parameters['DATA_WIDTH'] // 8
|
parameters['KEEP_WIDTH'] = parameters['DATA_WIDTH'] // 8
|
||||||
parameters['ID_ENABLE'] = 1
|
parameters['ID_ENABLE'] = 1
|
||||||
parameters['ID_WIDTH'] = 8
|
parameters['S_ID_WIDTH'] = 8
|
||||||
|
parameters['M_ID_WIDTH'] = parameters['S_ID_WIDTH'] + (ports-1).bit_length()
|
||||||
parameters['DEST_ENABLE'] = 1
|
parameters['DEST_ENABLE'] = 1
|
||||||
parameters['DEST_WIDTH'] = 8
|
parameters['DEST_WIDTH'] = 8
|
||||||
parameters['USER_ENABLE'] = 1
|
parameters['USER_ENABLE'] = 1
|
||||||
parameters['USER_WIDTH'] = 1
|
parameters['USER_WIDTH'] = 1
|
||||||
parameters['LAST_ENABLE'] = 1
|
parameters['LAST_ENABLE'] = 1
|
||||||
|
parameters['UPDATE_TID'] = 1
|
||||||
parameters['ARB_TYPE_ROUND_ROBIN'] = round_robin
|
parameters['ARB_TYPE_ROUND_ROBIN'] = round_robin
|
||||||
parameters['ARB_LSB_HIGH_PRIORITY'] = 1
|
parameters['ARB_LSB_HIGH_PRIORITY'] = 1
|
||||||
|
|
||||||
extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()}
|
extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()}
|
||||||
|
|
||||||
|
extra_env['PORTS'] = str(ports)
|
||||||
|
|
||||||
sim_build = os.path.join(tests_dir, "sim_build",
|
sim_build = os.path.join(tests_dir, "sim_build",
|
||||||
request.node.name.replace('[', '-').replace(']', ''))
|
request.node.name.replace('[', '-').replace(']', ''))
|
||||||
|
|
||||||
|
@ -68,12 +68,12 @@ class TB(object):
|
|||||||
self.dut.s_rst.setimmediatevalue(0)
|
self.dut.s_rst.setimmediatevalue(0)
|
||||||
for k in range(10):
|
for k in range(10):
|
||||||
await RisingEdge(self.dut.s_clk)
|
await RisingEdge(self.dut.s_clk)
|
||||||
self.dut.m_rst <= 1
|
self.dut.m_rst.value = 1
|
||||||
self.dut.s_rst <= 1
|
self.dut.s_rst.value = 1
|
||||||
for k in range(10):
|
for k in range(10):
|
||||||
await RisingEdge(self.dut.s_clk)
|
await RisingEdge(self.dut.s_clk)
|
||||||
self.dut.m_rst <= 0
|
self.dut.m_rst.value = 0
|
||||||
self.dut.s_rst <= 0
|
self.dut.s_rst.value = 0
|
||||||
for k in range(10):
|
for k in range(10):
|
||||||
await RisingEdge(self.dut.s_clk)
|
await RisingEdge(self.dut.s_clk)
|
||||||
|
|
||||||
@ -81,10 +81,10 @@ class TB(object):
|
|||||||
self.dut.s_rst.setimmediatevalue(0)
|
self.dut.s_rst.setimmediatevalue(0)
|
||||||
for k in range(10):
|
for k in range(10):
|
||||||
await RisingEdge(self.dut.s_clk)
|
await RisingEdge(self.dut.s_clk)
|
||||||
self.dut.s_rst <= 1
|
self.dut.s_rst.value = 1
|
||||||
for k in range(10):
|
for k in range(10):
|
||||||
await RisingEdge(self.dut.s_clk)
|
await RisingEdge(self.dut.s_clk)
|
||||||
self.dut.s_rst <= 0
|
self.dut.s_rst.value = 0
|
||||||
for k in range(10):
|
for k in range(10):
|
||||||
await RisingEdge(self.dut.s_clk)
|
await RisingEdge(self.dut.s_clk)
|
||||||
|
|
||||||
@ -92,10 +92,10 @@ class TB(object):
|
|||||||
self.dut.m_rst.setimmediatevalue(0)
|
self.dut.m_rst.setimmediatevalue(0)
|
||||||
for k in range(10):
|
for k in range(10):
|
||||||
await RisingEdge(self.dut.m_clk)
|
await RisingEdge(self.dut.m_clk)
|
||||||
self.dut.m_rst <= 1
|
self.dut.m_rst.value = 1
|
||||||
for k in range(10):
|
for k in range(10):
|
||||||
await RisingEdge(self.dut.m_clk)
|
await RisingEdge(self.dut.m_clk)
|
||||||
self.dut.m_rst <= 0
|
self.dut.m_rst.value = 0
|
||||||
for k in range(10):
|
for k in range(10):
|
||||||
await RisingEdge(self.dut.m_clk)
|
await RisingEdge(self.dut.m_clk)
|
||||||
|
|
||||||
|
@ -65,12 +65,12 @@ class TB(object):
|
|||||||
self.dut.s_rst.setimmediatevalue(0)
|
self.dut.s_rst.setimmediatevalue(0)
|
||||||
for k in range(10):
|
for k in range(10):
|
||||||
await RisingEdge(self.dut.s_clk)
|
await RisingEdge(self.dut.s_clk)
|
||||||
self.dut.m_rst <= 1
|
self.dut.m_rst.value = 1
|
||||||
self.dut.s_rst <= 1
|
self.dut.s_rst.value = 1
|
||||||
for k in range(10):
|
for k in range(10):
|
||||||
await RisingEdge(self.dut.s_clk)
|
await RisingEdge(self.dut.s_clk)
|
||||||
self.dut.m_rst <= 0
|
self.dut.m_rst.value = 0
|
||||||
self.dut.s_rst <= 0
|
self.dut.s_rst.value = 0
|
||||||
for k in range(10):
|
for k in range(10):
|
||||||
await RisingEdge(self.dut.s_clk)
|
await RisingEdge(self.dut.s_clk)
|
||||||
|
|
||||||
@ -78,10 +78,10 @@ class TB(object):
|
|||||||
self.dut.s_rst.setimmediatevalue(0)
|
self.dut.s_rst.setimmediatevalue(0)
|
||||||
for k in range(10):
|
for k in range(10):
|
||||||
await RisingEdge(self.dut.s_clk)
|
await RisingEdge(self.dut.s_clk)
|
||||||
self.dut.s_rst <= 1
|
self.dut.s_rst.value = 1
|
||||||
for k in range(10):
|
for k in range(10):
|
||||||
await RisingEdge(self.dut.s_clk)
|
await RisingEdge(self.dut.s_clk)
|
||||||
self.dut.s_rst <= 0
|
self.dut.s_rst.value = 0
|
||||||
for k in range(10):
|
for k in range(10):
|
||||||
await RisingEdge(self.dut.s_clk)
|
await RisingEdge(self.dut.s_clk)
|
||||||
|
|
||||||
@ -89,10 +89,10 @@ class TB(object):
|
|||||||
self.dut.m_rst.setimmediatevalue(0)
|
self.dut.m_rst.setimmediatevalue(0)
|
||||||
for k in range(10):
|
for k in range(10):
|
||||||
await RisingEdge(self.dut.m_clk)
|
await RisingEdge(self.dut.m_clk)
|
||||||
self.dut.m_rst <= 1
|
self.dut.m_rst.value = 1
|
||||||
for k in range(10):
|
for k in range(10):
|
||||||
await RisingEdge(self.dut.m_clk)
|
await RisingEdge(self.dut.m_clk)
|
||||||
self.dut.m_rst <= 0
|
self.dut.m_rst.value = 0
|
||||||
for k in range(10):
|
for k in range(10):
|
||||||
await RisingEdge(self.dut.m_clk)
|
await RisingEdge(self.dut.m_clk)
|
||||||
|
|
||||||
|
@ -66,10 +66,10 @@ class TB(object):
|
|||||||
self.dut.rst.setimmediatevalue(0)
|
self.dut.rst.setimmediatevalue(0)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
self.dut.rst <= 1
|
self.dut.rst.value = 1
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
self.dut.rst <= 0
|
self.dut.rst.value = 0
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
|
|
||||||
|
@ -129,10 +129,10 @@ class TB(object):
|
|||||||
self.dut.rst.setimmediatevalue(0)
|
self.dut.rst.setimmediatevalue(0)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
self.dut.rst <= 1
|
self.dut.rst.value = 1
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
self.dut.rst <= 0
|
self.dut.rst.value = 0
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
|
|
||||||
|
@ -130,10 +130,10 @@ class TB(object):
|
|||||||
self.dut.rst.setimmediatevalue(0)
|
self.dut.rst.setimmediatevalue(0)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
self.dut.rst <= 1
|
self.dut.rst.value = 1
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
self.dut.rst <= 0
|
self.dut.rst.value = 0
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
|
|
||||||
|
@ -42,9 +42,11 @@ export PARAM_KEEP_WIDTH ?= $(shell expr $(PARAM_DATA_WIDTH) / 8 )
|
|||||||
export PARAM_ID_ENABLE ?= 1
|
export PARAM_ID_ENABLE ?= 1
|
||||||
export PARAM_ID_WIDTH ?= 8
|
export PARAM_ID_WIDTH ?= 8
|
||||||
export PARAM_DEST_ENABLE ?= 1
|
export PARAM_DEST_ENABLE ?= 1
|
||||||
export PARAM_DEST_WIDTH ?= 8
|
export PARAM_M_DEST_WIDTH ?= 8
|
||||||
|
export PARAM_S_DEST_WIDTH ?= $(shell python -c "print($(PARAM_M_DEST_WIDTH) + ($(PORTS)-1).bit_length())")
|
||||||
export PARAM_USER_ENABLE ?= 1
|
export PARAM_USER_ENABLE ?= 1
|
||||||
export PARAM_USER_WIDTH ?= 1
|
export PARAM_USER_WIDTH ?= 1
|
||||||
|
export PARAM_TDEST_ROUTE ?= 1
|
||||||
|
|
||||||
ifeq ($(SIM), icarus)
|
ifeq ($(SIM), icarus)
|
||||||
PLUSARGS += -fst
|
PLUSARGS += -fst
|
||||||
@ -55,9 +57,11 @@ ifeq ($(SIM), icarus)
|
|||||||
COMPILE_ARGS += -P $(TOPLEVEL).ID_ENABLE=$(PARAM_ID_ENABLE)
|
COMPILE_ARGS += -P $(TOPLEVEL).ID_ENABLE=$(PARAM_ID_ENABLE)
|
||||||
COMPILE_ARGS += -P $(TOPLEVEL).ID_WIDTH=$(PARAM_ID_WIDTH)
|
COMPILE_ARGS += -P $(TOPLEVEL).ID_WIDTH=$(PARAM_ID_WIDTH)
|
||||||
COMPILE_ARGS += -P $(TOPLEVEL).DEST_ENABLE=$(PARAM_DEST_ENABLE)
|
COMPILE_ARGS += -P $(TOPLEVEL).DEST_ENABLE=$(PARAM_DEST_ENABLE)
|
||||||
COMPILE_ARGS += -P $(TOPLEVEL).DEST_WIDTH=$(PARAM_DEST_WIDTH)
|
COMPILE_ARGS += -P $(TOPLEVEL).S_DEST_WIDTH=$(PARAM_S_DEST_WIDTH)
|
||||||
|
COMPILE_ARGS += -P $(TOPLEVEL).M_DEST_WIDTH=$(PARAM_M_DEST_WIDTH)
|
||||||
COMPILE_ARGS += -P $(TOPLEVEL).USER_ENABLE=$(PARAM_USER_ENABLE)
|
COMPILE_ARGS += -P $(TOPLEVEL).USER_ENABLE=$(PARAM_USER_ENABLE)
|
||||||
COMPILE_ARGS += -P $(TOPLEVEL).USER_WIDTH=$(PARAM_USER_WIDTH)
|
COMPILE_ARGS += -P $(TOPLEVEL).USER_WIDTH=$(PARAM_USER_WIDTH)
|
||||||
|
COMPILE_ARGS += -P $(TOPLEVEL).TDEST_ROUTE=$(PARAM_TDEST_ROUTE)
|
||||||
|
|
||||||
ifeq ($(WAVES), 1)
|
ifeq ($(WAVES), 1)
|
||||||
VERILOG_SOURCES += iverilog_dump.v
|
VERILOG_SOURCES += iverilog_dump.v
|
||||||
@ -72,9 +76,11 @@ else ifeq ($(SIM), verilator)
|
|||||||
COMPILE_ARGS += -GID_ENABLE=$(PARAM_ID_ENABLE)
|
COMPILE_ARGS += -GID_ENABLE=$(PARAM_ID_ENABLE)
|
||||||
COMPILE_ARGS += -GID_WIDTH=$(PARAM_ID_WIDTH)
|
COMPILE_ARGS += -GID_WIDTH=$(PARAM_ID_WIDTH)
|
||||||
COMPILE_ARGS += -GDEST_ENABLE=$(PARAM_DEST_ENABLE)
|
COMPILE_ARGS += -GDEST_ENABLE=$(PARAM_DEST_ENABLE)
|
||||||
COMPILE_ARGS += -GDEST_WIDTH=$(PARAM_DEST_WIDTH)
|
COMPILE_ARGS += -GS_DEST_WIDTH=$(PARAM_S_DEST_WIDTH)
|
||||||
|
COMPILE_ARGS += -GM_DEST_WIDTH=$(PARAM_M_DEST_WIDTH)
|
||||||
COMPILE_ARGS += -GUSER_ENABLE=$(PARAM_USER_ENABLE)
|
COMPILE_ARGS += -GUSER_ENABLE=$(PARAM_USER_ENABLE)
|
||||||
COMPILE_ARGS += -GUSER_WIDTH=$(PARAM_USER_WIDTH)
|
COMPILE_ARGS += -GUSER_WIDTH=$(PARAM_USER_WIDTH)
|
||||||
|
COMPILE_ARGS += -GTDEST_ROUTE=$(PARAM_TDEST_ROUTE)
|
||||||
|
|
||||||
ifeq ($(WAVES), 1)
|
ifeq ($(WAVES), 1)
|
||||||
COMPILE_ARGS += --trace-fst
|
COMPILE_ARGS += --trace-fst
|
||||||
|
@ -43,7 +43,7 @@ class TB(object):
|
|||||||
def __init__(self, dut):
|
def __init__(self, dut):
|
||||||
self.dut = dut
|
self.dut = dut
|
||||||
|
|
||||||
ports = int(os.getenv("PORTS"))
|
ports = len(dut.axis_demux_inst.m_axis_tvalid)
|
||||||
|
|
||||||
self.log = logging.getLogger("cocotb.tb")
|
self.log = logging.getLogger("cocotb.tb")
|
||||||
self.log.setLevel(logging.DEBUG)
|
self.log.setLevel(logging.DEBUG)
|
||||||
@ -70,10 +70,10 @@ class TB(object):
|
|||||||
self.dut.rst.setimmediatevalue(0)
|
self.dut.rst.setimmediatevalue(0)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
self.dut.rst <= 1
|
self.dut.rst.value = 1
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
self.dut.rst <= 0
|
self.dut.rst.value = 0
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
|
|
||||||
@ -82,7 +82,13 @@ async def run_test(dut, payload_lengths=None, payload_data=None, idle_inserter=N
|
|||||||
|
|
||||||
tb = TB(dut)
|
tb = TB(dut)
|
||||||
|
|
||||||
id_count = 2**len(tb.source.bus.tid)
|
id_width = len(tb.source.bus.tid)
|
||||||
|
id_count = 2**id_width
|
||||||
|
id_mask = id_count-1
|
||||||
|
|
||||||
|
dest_width = len(tb.sink[0].bus.tid)
|
||||||
|
dest_count = 2**dest_width
|
||||||
|
dest_mask = dest_count-1
|
||||||
|
|
||||||
cur_id = 1
|
cur_id = 1
|
||||||
|
|
||||||
@ -100,7 +106,7 @@ async def run_test(dut, payload_lengths=None, payload_data=None, idle_inserter=N
|
|||||||
for test_data in [payload_data(x) for x in payload_lengths()]:
|
for test_data in [payload_data(x) for x in payload_lengths()]:
|
||||||
test_frame = AxiStreamFrame(test_data)
|
test_frame = AxiStreamFrame(test_data)
|
||||||
test_frame.tid = cur_id
|
test_frame.tid = cur_id
|
||||||
test_frame.tdest = cur_id
|
test_frame.tdest = cur_id | (port << dest_width)
|
||||||
|
|
||||||
test_frames.append(test_frame)
|
test_frames.append(test_frame)
|
||||||
await tb.source.send(test_frame)
|
await tb.source.send(test_frame)
|
||||||
@ -112,7 +118,7 @@ async def run_test(dut, payload_lengths=None, payload_data=None, idle_inserter=N
|
|||||||
|
|
||||||
assert rx_frame.tdata == test_frame.tdata
|
assert rx_frame.tdata == test_frame.tdata
|
||||||
assert rx_frame.tid == test_frame.tid
|
assert rx_frame.tid == test_frame.tid
|
||||||
assert rx_frame.tdest == test_frame.tdest
|
assert rx_frame.tdest == (test_frame.tdest & dest_mask)
|
||||||
assert not rx_frame.tuser
|
assert not rx_frame.tuser
|
||||||
|
|
||||||
assert tb.sink[port].empty()
|
assert tb.sink[port].empty()
|
||||||
@ -137,7 +143,7 @@ def incrementing_payload(length):
|
|||||||
|
|
||||||
if cocotb.SIM_NAME:
|
if cocotb.SIM_NAME:
|
||||||
|
|
||||||
ports = int(os.getenv("PORTS"))
|
ports = len(cocotb.top.axis_demux_inst.m_axis_tvalid)
|
||||||
|
|
||||||
factory = TestFactory(run_test)
|
factory = TestFactory(run_test)
|
||||||
factory.add_option("payload_lengths", [size_list])
|
factory.add_option("payload_lengths", [size_list])
|
||||||
@ -154,9 +160,10 @@ tests_dir = os.path.dirname(__file__)
|
|||||||
rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl'))
|
rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl'))
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("tdest_route", [0, 1])
|
||||||
@pytest.mark.parametrize("data_width", [8, 16, 32])
|
@pytest.mark.parametrize("data_width", [8, 16, 32])
|
||||||
@pytest.mark.parametrize("ports", [4])
|
@pytest.mark.parametrize("ports", [4])
|
||||||
def test_axis_demux(request, ports, data_width):
|
def test_axis_demux(request, ports, data_width, tdest_route):
|
||||||
dut = "axis_demux"
|
dut = "axis_demux"
|
||||||
wrapper = f"{dut}_wrap_{ports}"
|
wrapper = f"{dut}_wrap_{ports}"
|
||||||
module = os.path.splitext(os.path.basename(__file__))[0]
|
module = os.path.splitext(os.path.basename(__file__))[0]
|
||||||
@ -183,9 +190,11 @@ def test_axis_demux(request, ports, data_width):
|
|||||||
parameters['ID_ENABLE'] = 1
|
parameters['ID_ENABLE'] = 1
|
||||||
parameters['ID_WIDTH'] = 8
|
parameters['ID_WIDTH'] = 8
|
||||||
parameters['DEST_ENABLE'] = 1
|
parameters['DEST_ENABLE'] = 1
|
||||||
parameters['DEST_WIDTH'] = 8
|
parameters['M_DEST_WIDTH'] = 8
|
||||||
|
parameters['S_DEST_WIDTH'] = parameters['M_DEST_WIDTH'] + (ports-1).bit_length()
|
||||||
parameters['USER_ENABLE'] = 1
|
parameters['USER_ENABLE'] = 1
|
||||||
parameters['USER_WIDTH'] = 1
|
parameters['USER_WIDTH'] = 1
|
||||||
|
parameters['TDEST_ROUTE'] = tdest_route
|
||||||
|
|
||||||
extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()}
|
extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()}
|
||||||
|
|
||||||
|
@ -63,10 +63,10 @@ class TB(object):
|
|||||||
self.dut.rst.setimmediatevalue(0)
|
self.dut.rst.setimmediatevalue(0)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
self.dut.rst <= 1
|
self.dut.rst.value = 1
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
self.dut.rst <= 0
|
self.dut.rst.value = 0
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
|
|
||||||
|
@ -63,10 +63,10 @@ class TB(object):
|
|||||||
self.dut.rst.setimmediatevalue(0)
|
self.dut.rst.setimmediatevalue(0)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
self.dut.rst <= 1
|
self.dut.rst.value = 1
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
self.dut.rst <= 0
|
self.dut.rst.value = 0
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
|
|
||||||
|
@ -74,10 +74,10 @@ class TB(object):
|
|||||||
self.dut.rst.setimmediatevalue(0)
|
self.dut.rst.setimmediatevalue(0)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
self.dut.rst <= 1
|
self.dut.rst.value = 1
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
self.dut.rst <= 0
|
self.dut.rst.value = 0
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
|
|
||||||
@ -102,8 +102,8 @@ async def run_test(dut, payload_lengths=None, payload_data=None, idle_inserter=N
|
|||||||
tb.log.info("length_min %d, length_max %d", length_min, length_max)
|
tb.log.info("length_min %d, length_max %d", length_min, length_max)
|
||||||
|
|
||||||
await RisingEdge(dut.clk)
|
await RisingEdge(dut.clk)
|
||||||
tb.dut.length_min <= length_min
|
tb.dut.length_min.value = length_min
|
||||||
tb.dut.length_max <= length_max
|
tb.dut.length_max.value = length_max
|
||||||
await RisingEdge(dut.clk)
|
await RisingEdge(dut.clk)
|
||||||
|
|
||||||
test_frames = []
|
test_frames = []
|
||||||
|
@ -74,10 +74,10 @@ class TB(object):
|
|||||||
self.dut.rst.setimmediatevalue(0)
|
self.dut.rst.setimmediatevalue(0)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
self.dut.rst <= 1
|
self.dut.rst.value = 1
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
self.dut.rst <= 0
|
self.dut.rst.value = 0
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
|
|
||||||
@ -102,8 +102,8 @@ async def run_test(dut, payload_lengths=None, payload_data=None, idle_inserter=N
|
|||||||
tb.log.info("length_min %d, length_max %d", length_min, length_max)
|
tb.log.info("length_min %d, length_max %d", length_min, length_max)
|
||||||
|
|
||||||
await RisingEdge(dut.clk)
|
await RisingEdge(dut.clk)
|
||||||
tb.dut.length_min <= length_min
|
tb.dut.length_min.value = length_min
|
||||||
tb.dut.length_max <= length_max
|
tb.dut.length_max.value = length_max
|
||||||
await RisingEdge(dut.clk)
|
await RisingEdge(dut.clk)
|
||||||
|
|
||||||
test_frames = []
|
test_frames = []
|
||||||
|
@ -69,10 +69,10 @@ class TB(object):
|
|||||||
self.dut.rst.setimmediatevalue(0)
|
self.dut.rst.setimmediatevalue(0)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
self.dut.rst <= 1
|
self.dut.rst.value = 1
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
self.dut.rst <= 0
|
self.dut.rst.value = 0
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
|
|
||||||
|
@ -63,10 +63,10 @@ class TB(object):
|
|||||||
self.dut.rst.setimmediatevalue(0)
|
self.dut.rst.setimmediatevalue(0)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
self.dut.rst <= 1
|
self.dut.rst.value = 1
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
self.dut.rst <= 0
|
self.dut.rst.value = 0
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
|
|
||||||
|
@ -63,10 +63,10 @@ class TB(object):
|
|||||||
self.dut.rst.setimmediatevalue(0)
|
self.dut.rst.setimmediatevalue(0)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
self.dut.rst <= 1
|
self.dut.rst.value = 1
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
self.dut.rst <= 0
|
self.dut.rst.value = 0
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
|
|
||||||
|
@ -26,11 +26,11 @@ WAVES ?= 0
|
|||||||
COCOTB_HDL_TIMEUNIT = 1ns
|
COCOTB_HDL_TIMEUNIT = 1ns
|
||||||
COCOTB_HDL_TIMEPRECISION = 1ps
|
COCOTB_HDL_TIMEPRECISION = 1ps
|
||||||
|
|
||||||
export PARAM_S_COUNT ?= 4
|
export S_COUNT ?= 4
|
||||||
export PARAM_M_COUNT ?= 4
|
export M_COUNT ?= 4
|
||||||
|
|
||||||
DUT = axis_ram_switch
|
DUT = axis_ram_switch
|
||||||
WRAPPER = $(DUT)_wrap_$(PARAM_S_COUNT)x$(PARAM_M_COUNT)
|
WRAPPER = $(DUT)_wrap_$(S_COUNT)x$(M_COUNT)
|
||||||
TOPLEVEL = $(WRAPPER)
|
TOPLEVEL = $(WRAPPER)
|
||||||
MODULE = test_$(DUT)
|
MODULE = test_$(DUT)
|
||||||
VERILOG_SOURCES += $(WRAPPER).v
|
VERILOG_SOURCES += $(WRAPPER).v
|
||||||
@ -50,14 +50,17 @@ export PARAM_M_DATA_WIDTH ?= 8
|
|||||||
export PARAM_M_KEEP_ENABLE ?= $(shell expr $(PARAM_M_DATA_WIDTH) \> 8 )
|
export PARAM_M_KEEP_ENABLE ?= $(shell expr $(PARAM_M_DATA_WIDTH) \> 8 )
|
||||||
export PARAM_M_KEEP_WIDTH ?= $(shell expr $(PARAM_M_DATA_WIDTH) / 8 )
|
export PARAM_M_KEEP_WIDTH ?= $(shell expr $(PARAM_M_DATA_WIDTH) / 8 )
|
||||||
export PARAM_ID_ENABLE ?= 1
|
export PARAM_ID_ENABLE ?= 1
|
||||||
export PARAM_ID_WIDTH ?= 16
|
export PARAM_S_ID_WIDTH ?= 16
|
||||||
export PARAM_DEST_WIDTH ?= 8
|
export PARAM_M_ID_WIDTH ?= $(shell python -c "print($(PARAM_S_ID_WIDTH) + ($(S_COUNT)-1).bit_length())")
|
||||||
|
export PARAM_M_DEST_WIDTH ?= 8
|
||||||
|
export PARAM_S_DEST_WIDTH ?= $(shell python -c "print($(PARAM_M_DEST_WIDTH) + ($(M_COUNT)-1).bit_length())")
|
||||||
export PARAM_USER_ENABLE ?= 1
|
export PARAM_USER_ENABLE ?= 1
|
||||||
export PARAM_USER_WIDTH ?= 1
|
export PARAM_USER_WIDTH ?= 1
|
||||||
export PARAM_USER_BAD_FRAME_VALUE ?= 1
|
export PARAM_USER_BAD_FRAME_VALUE ?= 1
|
||||||
export PARAM_USER_BAD_FRAME_MASK ?= 1
|
export PARAM_USER_BAD_FRAME_MASK ?= 1
|
||||||
export PARAM_DROP_BAD_FRAME ?= 0
|
export PARAM_DROP_BAD_FRAME ?= 0
|
||||||
export PARAM_DROP_WHEN_FULL ?= 0
|
export PARAM_DROP_WHEN_FULL ?= 0
|
||||||
|
export PARAM_UPDATE_TID ?= 1
|
||||||
export PARAM_ARB_TYPE_ROUND_ROBIN ?= 1
|
export PARAM_ARB_TYPE_ROUND_ROBIN ?= 1
|
||||||
export PARAM_ARB_LSB_HIGH_PRIORITY ?= 1
|
export PARAM_ARB_LSB_HIGH_PRIORITY ?= 1
|
||||||
export PARAM_RAM_PIPELINE ?= 2
|
export PARAM_RAM_PIPELINE ?= 2
|
||||||
@ -75,14 +78,17 @@ ifeq ($(SIM), icarus)
|
|||||||
COMPILE_ARGS += -P $(TOPLEVEL).M_KEEP_ENABLE=$(PARAM_M_KEEP_ENABLE)
|
COMPILE_ARGS += -P $(TOPLEVEL).M_KEEP_ENABLE=$(PARAM_M_KEEP_ENABLE)
|
||||||
COMPILE_ARGS += -P $(TOPLEVEL).M_KEEP_WIDTH=$(PARAM_M_KEEP_WIDTH)
|
COMPILE_ARGS += -P $(TOPLEVEL).M_KEEP_WIDTH=$(PARAM_M_KEEP_WIDTH)
|
||||||
COMPILE_ARGS += -P $(TOPLEVEL).ID_ENABLE=$(PARAM_ID_ENABLE)
|
COMPILE_ARGS += -P $(TOPLEVEL).ID_ENABLE=$(PARAM_ID_ENABLE)
|
||||||
COMPILE_ARGS += -P $(TOPLEVEL).ID_WIDTH=$(PARAM_ID_WIDTH)
|
COMPILE_ARGS += -P $(TOPLEVEL).S_ID_WIDTH=$(PARAM_S_ID_WIDTH)
|
||||||
COMPILE_ARGS += -P $(TOPLEVEL).DEST_WIDTH=$(PARAM_DEST_WIDTH)
|
COMPILE_ARGS += -P $(TOPLEVEL).M_ID_WIDTH=$(PARAM_M_ID_WIDTH)
|
||||||
|
COMPILE_ARGS += -P $(TOPLEVEL).S_DEST_WIDTH=$(PARAM_S_DEST_WIDTH)
|
||||||
|
COMPILE_ARGS += -P $(TOPLEVEL).M_DEST_WIDTH=$(PARAM_M_DEST_WIDTH)
|
||||||
COMPILE_ARGS += -P $(TOPLEVEL).USER_ENABLE=$(PARAM_USER_ENABLE)
|
COMPILE_ARGS += -P $(TOPLEVEL).USER_ENABLE=$(PARAM_USER_ENABLE)
|
||||||
COMPILE_ARGS += -P $(TOPLEVEL).USER_WIDTH=$(PARAM_USER_WIDTH)
|
COMPILE_ARGS += -P $(TOPLEVEL).USER_WIDTH=$(PARAM_USER_WIDTH)
|
||||||
COMPILE_ARGS += -P $(TOPLEVEL).USER_BAD_FRAME_VALUE=$(PARAM_USER_BAD_FRAME_VALUE)
|
COMPILE_ARGS += -P $(TOPLEVEL).USER_BAD_FRAME_VALUE=$(PARAM_USER_BAD_FRAME_VALUE)
|
||||||
COMPILE_ARGS += -P $(TOPLEVEL).USER_BAD_FRAME_MASK=$(PARAM_USER_BAD_FRAME_MASK)
|
COMPILE_ARGS += -P $(TOPLEVEL).USER_BAD_FRAME_MASK=$(PARAM_USER_BAD_FRAME_MASK)
|
||||||
COMPILE_ARGS += -P $(TOPLEVEL).DROP_BAD_FRAME=$(PARAM_DROP_BAD_FRAME)
|
COMPILE_ARGS += -P $(TOPLEVEL).DROP_BAD_FRAME=$(PARAM_DROP_BAD_FRAME)
|
||||||
COMPILE_ARGS += -P $(TOPLEVEL).DROP_WHEN_FULL=$(PARAM_DROP_WHEN_FULL)
|
COMPILE_ARGS += -P $(TOPLEVEL).DROP_WHEN_FULL=$(PARAM_DROP_WHEN_FULL)
|
||||||
|
COMPILE_ARGS += -P $(TOPLEVEL).UPDATE_TID=$(PARAM_UPDATE_TID)
|
||||||
COMPILE_ARGS += -P $(TOPLEVEL).ARB_TYPE_ROUND_ROBIN=$(PARAM_ARB_TYPE_ROUND_ROBIN)
|
COMPILE_ARGS += -P $(TOPLEVEL).ARB_TYPE_ROUND_ROBIN=$(PARAM_ARB_TYPE_ROUND_ROBIN)
|
||||||
COMPILE_ARGS += -P $(TOPLEVEL).ARB_LSB_HIGH_PRIORITY=$(PARAM_ARB_LSB_HIGH_PRIORITY)
|
COMPILE_ARGS += -P $(TOPLEVEL).ARB_LSB_HIGH_PRIORITY=$(PARAM_ARB_LSB_HIGH_PRIORITY)
|
||||||
COMPILE_ARGS += -P $(TOPLEVEL).RAM_PIPELINE=$(PARAM_RAM_PIPELINE)
|
COMPILE_ARGS += -P $(TOPLEVEL).RAM_PIPELINE=$(PARAM_RAM_PIPELINE)
|
||||||
@ -104,14 +110,17 @@ else ifeq ($(SIM), verilator)
|
|||||||
COMPILE_ARGS += -GM_KEEP_ENABLE=$(PARAM_M_KEEP_ENABLE)
|
COMPILE_ARGS += -GM_KEEP_ENABLE=$(PARAM_M_KEEP_ENABLE)
|
||||||
COMPILE_ARGS += -GM_KEEP_WIDTH=$(PARAM_M_KEEP_WIDTH)
|
COMPILE_ARGS += -GM_KEEP_WIDTH=$(PARAM_M_KEEP_WIDTH)
|
||||||
COMPILE_ARGS += -GID_ENABLE=$(PARAM_ID_ENABLE)
|
COMPILE_ARGS += -GID_ENABLE=$(PARAM_ID_ENABLE)
|
||||||
COMPILE_ARGS += -GID_WIDTH=$(PARAM_ID_WIDTH)
|
COMPILE_ARGS += -GS_ID_WIDTH=$(PARAM_S_ID_WIDTH)
|
||||||
COMPILE_ARGS += -GDEST_WIDTH=$(PARAM_DEST_WIDTH)
|
COMPILE_ARGS += -GM_ID_WIDTH=$(PARAM_M_ID_WIDTH)
|
||||||
|
COMPILE_ARGS += -GS_DEST_WIDTH=$(PARAM_S_DEST_WIDTH)
|
||||||
|
COMPILE_ARGS += -GM_DEST_WIDTH=$(PARAM_M_DEST_WIDTH)
|
||||||
COMPILE_ARGS += -GUSER_ENABLE=$(PARAM_USER_ENABLE)
|
COMPILE_ARGS += -GUSER_ENABLE=$(PARAM_USER_ENABLE)
|
||||||
COMPILE_ARGS += -GUSER_WIDTH=$(PARAM_USER_WIDTH)
|
COMPILE_ARGS += -GUSER_WIDTH=$(PARAM_USER_WIDTH)
|
||||||
COMPILE_ARGS += -GUSER_BAD_FRAME_VALUE=$(PARAM_USER_BAD_FRAME_VALUE)
|
COMPILE_ARGS += -GUSER_BAD_FRAME_VALUE=$(PARAM_USER_BAD_FRAME_VALUE)
|
||||||
COMPILE_ARGS += -GUSER_BAD_FRAME_MASK=$(PARAM_USER_BAD_FRAME_MASK)
|
COMPILE_ARGS += -GUSER_BAD_FRAME_MASK=$(PARAM_USER_BAD_FRAME_MASK)
|
||||||
COMPILE_ARGS += -GDROP_BAD_FRAME=$(PARAM_DROP_BAD_FRAME)
|
COMPILE_ARGS += -GDROP_BAD_FRAME=$(PARAM_DROP_BAD_FRAME)
|
||||||
COMPILE_ARGS += -GDROP_WHEN_FULL=$(PARAM_DROP_WHEN_FULL)
|
COMPILE_ARGS += -GDROP_WHEN_FULL=$(PARAM_DROP_WHEN_FULL)
|
||||||
|
COMPILE_ARGS += -GUPDATE_TID=$(PARAM_UPDATE_TID)
|
||||||
COMPILE_ARGS += -GARB_TYPE_ROUND_ROBIN=$(PARAM_ARB_TYPE_ROUND_ROBIN)
|
COMPILE_ARGS += -GARB_TYPE_ROUND_ROBIN=$(PARAM_ARB_TYPE_ROUND_ROBIN)
|
||||||
COMPILE_ARGS += -GARB_LSB_HIGH_PRIORITY=$(PARAM_ARB_LSB_HIGH_PRIORITY)
|
COMPILE_ARGS += -GARB_LSB_HIGH_PRIORITY=$(PARAM_ARB_LSB_HIGH_PRIORITY)
|
||||||
COMPILE_ARGS += -GRAM_PIPELINE=$(PARAM_RAM_PIPELINE)
|
COMPILE_ARGS += -GRAM_PIPELINE=$(PARAM_RAM_PIPELINE)
|
||||||
@ -124,7 +133,7 @@ endif
|
|||||||
include $(shell cocotb-config --makefiles)/Makefile.sim
|
include $(shell cocotb-config --makefiles)/Makefile.sim
|
||||||
|
|
||||||
$(WRAPPER).v: ../../rtl/$(DUT)_wrap.py
|
$(WRAPPER).v: ../../rtl/$(DUT)_wrap.py
|
||||||
$< -p $(PARAM_S_COUNT) $(PARAM_M_COUNT)
|
$< -p $(S_COUNT) $(M_COUNT)
|
||||||
|
|
||||||
iverilog_dump.v:
|
iverilog_dump.v:
|
||||||
echo 'module iverilog_dump();' > $@
|
echo 'module iverilog_dump();' > $@
|
||||||
|
@ -69,10 +69,10 @@ class TB(object):
|
|||||||
self.dut.rst.setimmediatevalue(0)
|
self.dut.rst.setimmediatevalue(0)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
self.dut.rst <= 1
|
self.dut.rst.value = 1
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
self.dut.rst <= 0
|
self.dut.rst.value = 0
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
|
|
||||||
@ -81,7 +81,15 @@ async def run_test(dut, payload_lengths=None, payload_data=None, idle_inserter=N
|
|||||||
|
|
||||||
tb = TB(dut)
|
tb = TB(dut)
|
||||||
|
|
||||||
id_count = 2**len(tb.source[s].bus.tid)
|
id_width = len(tb.source[0].bus.tid)
|
||||||
|
id_count = 2**id_width
|
||||||
|
id_mask = id_count-1
|
||||||
|
|
||||||
|
src_width = (len(tb.source)-1).bit_length()
|
||||||
|
src_mask = 2**src_width-1 if src_width else 0
|
||||||
|
src_shift = id_width-src_width
|
||||||
|
max_count = 2**src_shift
|
||||||
|
count_mask = max_count-1
|
||||||
|
|
||||||
cur_id = 1
|
cur_id = 1
|
||||||
|
|
||||||
@ -94,19 +102,21 @@ async def run_test(dut, payload_lengths=None, payload_data=None, idle_inserter=N
|
|||||||
|
|
||||||
for test_data in [payload_data(x) for x in payload_lengths()]:
|
for test_data in [payload_data(x) for x in payload_lengths()]:
|
||||||
test_frame = AxiStreamFrame(test_data)
|
test_frame = AxiStreamFrame(test_data)
|
||||||
test_frame.tid = cur_id
|
test_frame.tid = cur_id | (s << src_shift)
|
||||||
test_frame.tdest = m
|
test_frame.tdest = m
|
||||||
|
|
||||||
test_frames.append(test_frame)
|
test_frames.append(test_frame)
|
||||||
await tb.source[s].send(test_frame)
|
await tb.source[s].send(test_frame)
|
||||||
|
|
||||||
cur_id = (cur_id + 1) % id_count
|
cur_id = (cur_id + 1) % max_count
|
||||||
|
|
||||||
for test_frame in test_frames:
|
for test_frame in test_frames:
|
||||||
rx_frame = await tb.sink[m].recv()
|
rx_frame = await tb.sink[m].recv()
|
||||||
|
|
||||||
assert rx_frame.tdata == test_frame.tdata
|
assert rx_frame.tdata == test_frame.tdata
|
||||||
assert rx_frame.tid == test_frame.tid
|
assert (rx_frame.tid & id_mask) == test_frame.tid
|
||||||
|
assert ((rx_frame.tid >> src_shift) & src_mask) == s
|
||||||
|
assert (rx_frame.tid >> id_width) == s
|
||||||
assert rx_frame.tdest == test_frame.tdest
|
assert rx_frame.tdest == test_frame.tdest
|
||||||
assert not rx_frame.tuser
|
assert not rx_frame.tuser
|
||||||
|
|
||||||
@ -142,7 +152,15 @@ async def run_arb_test(dut):
|
|||||||
tb = TB(dut)
|
tb = TB(dut)
|
||||||
|
|
||||||
byte_lanes = max(tb.source[0].byte_lanes, tb.sink[0].byte_lanes)
|
byte_lanes = max(tb.source[0].byte_lanes, tb.sink[0].byte_lanes)
|
||||||
id_count = 2**len(tb.source[0].bus.tid)
|
id_width = len(tb.source[0].bus.tid)
|
||||||
|
id_count = 2**id_width
|
||||||
|
id_mask = id_count-1
|
||||||
|
|
||||||
|
src_width = (len(tb.source)-1).bit_length()
|
||||||
|
src_mask = 2**src_width-1 if src_width else 0
|
||||||
|
src_shift = id_width-src_width
|
||||||
|
max_count = 2**src_shift
|
||||||
|
count_mask = max_count-1
|
||||||
|
|
||||||
cur_id = 1
|
cur_id = 1
|
||||||
|
|
||||||
@ -155,8 +173,6 @@ async def run_arb_test(dut):
|
|||||||
|
|
||||||
for k in range(5):
|
for k in range(5):
|
||||||
test_frame = AxiStreamFrame(test_data, tx_complete=Event())
|
test_frame = AxiStreamFrame(test_data, tx_complete=Event())
|
||||||
test_frame.tid = cur_id
|
|
||||||
test_frame.tdest = 0
|
|
||||||
|
|
||||||
src_ind = 0
|
src_ind = 0
|
||||||
|
|
||||||
@ -170,17 +186,21 @@ async def run_arb_test(dut):
|
|||||||
else:
|
else:
|
||||||
src_ind = 1
|
src_ind = 1
|
||||||
|
|
||||||
|
test_frame.tid = cur_id | (src_ind << src_shift)
|
||||||
|
test_frame.tdest = 0
|
||||||
|
|
||||||
test_frames.append(test_frame)
|
test_frames.append(test_frame)
|
||||||
await tb.source[src_ind].send(test_frame)
|
await tb.source[src_ind].send(test_frame)
|
||||||
|
|
||||||
cur_id = (cur_id + 1) % id_count
|
cur_id = (cur_id + 1) % max_count
|
||||||
|
|
||||||
for k in [0, 1, 2, 4, 3]:
|
for k in [0, 1, 2, 4, 3]:
|
||||||
test_frame = test_frames[k]
|
test_frame = test_frames[k]
|
||||||
rx_frame = await tb.sink[0].recv()
|
rx_frame = await tb.sink[0].recv()
|
||||||
|
|
||||||
assert rx_frame.tdata == test_frame.tdata
|
assert rx_frame.tdata == test_frame.tdata
|
||||||
assert rx_frame.tid == test_frame.tid
|
assert (rx_frame.tid & id_mask) == test_frame.tid
|
||||||
|
assert ((rx_frame.tid >> src_shift) & src_mask) == (rx_frame.tid >> id_width)
|
||||||
assert rx_frame.tdest == test_frame.tdest
|
assert rx_frame.tdest == test_frame.tdest
|
||||||
assert not rx_frame.tuser
|
assert not rx_frame.tuser
|
||||||
|
|
||||||
@ -195,7 +215,15 @@ async def run_stress_test(dut, idle_inserter=None, backpressure_inserter=None):
|
|||||||
tb = TB(dut)
|
tb = TB(dut)
|
||||||
|
|
||||||
byte_lanes = max(tb.source[0].byte_lanes, tb.sink[0].byte_lanes)
|
byte_lanes = max(tb.source[0].byte_lanes, tb.sink[0].byte_lanes)
|
||||||
id_count = 2**len(tb.source[0].bus.tid)
|
id_width = len(tb.source[0].bus.tid)
|
||||||
|
id_count = 2**id_width
|
||||||
|
id_mask = id_count-1
|
||||||
|
|
||||||
|
src_width = (len(tb.source)-1).bit_length()
|
||||||
|
src_mask = 2**src_width-1 if src_width else 0
|
||||||
|
src_shift = id_width-src_width
|
||||||
|
max_count = 2**src_shift
|
||||||
|
count_mask = max_count-1
|
||||||
|
|
||||||
cur_id = 1
|
cur_id = 1
|
||||||
|
|
||||||
@ -211,13 +239,13 @@ async def run_stress_test(dut, idle_inserter=None, backpressure_inserter=None):
|
|||||||
length = random.randint(1, byte_lanes*16)
|
length = random.randint(1, byte_lanes*16)
|
||||||
test_data = bytearray(itertools.islice(itertools.cycle(range(256)), length))
|
test_data = bytearray(itertools.islice(itertools.cycle(range(256)), length))
|
||||||
test_frame = AxiStreamFrame(test_data)
|
test_frame = AxiStreamFrame(test_data)
|
||||||
test_frame.tid = cur_id
|
test_frame.tid = cur_id | (p << src_shift)
|
||||||
test_frame.tdest = random.randrange(len(tb.sink))
|
test_frame.tdest = random.randrange(len(tb.sink))
|
||||||
|
|
||||||
test_frames[p][test_frame.tdest].append(test_frame)
|
test_frames[p][test_frame.tdest].append(test_frame)
|
||||||
await tb.source[p].send(test_frame)
|
await tb.source[p].send(test_frame)
|
||||||
|
|
||||||
cur_id = (cur_id + 1) % id_count
|
cur_id = (cur_id + 1) % max_count
|
||||||
|
|
||||||
for lst in test_frames:
|
for lst in test_frames:
|
||||||
while any(lst):
|
while any(lst):
|
||||||
@ -227,14 +255,15 @@ async def run_stress_test(dut, idle_inserter=None, backpressure_inserter=None):
|
|||||||
|
|
||||||
for lst_a in test_frames:
|
for lst_a in test_frames:
|
||||||
for lst_b in lst_a:
|
for lst_b in lst_a:
|
||||||
if lst_b and lst_b[0].tid == rx_frame.tid:
|
if lst_b and lst_b[0].tid == (rx_frame.tid & id_mask):
|
||||||
test_frame = lst_b.pop(0)
|
test_frame = lst_b.pop(0)
|
||||||
break
|
break
|
||||||
|
|
||||||
assert test_frame is not None
|
assert test_frame is not None
|
||||||
|
|
||||||
assert rx_frame.tdata == test_frame.tdata
|
assert rx_frame.tdata == test_frame.tdata
|
||||||
assert rx_frame.tid == test_frame.tid
|
assert (rx_frame.tid & id_mask) == test_frame.tid
|
||||||
|
assert ((rx_frame.tid >> src_shift) & src_mask) == (rx_frame.tid >> id_width)
|
||||||
assert rx_frame.tdest == test_frame.tdest
|
assert rx_frame.tdest == test_frame.tdest
|
||||||
assert not rx_frame.tuser
|
assert not rx_frame.tuser
|
||||||
|
|
||||||
@ -322,9 +351,6 @@ def test_axis_ram_switch(request, s_count, m_count, s_data_width, m_data_width):
|
|||||||
|
|
||||||
parameters = {}
|
parameters = {}
|
||||||
|
|
||||||
parameters['S_COUNT'] = s_count
|
|
||||||
parameters['M_COUNT'] = m_count
|
|
||||||
|
|
||||||
parameters['FIFO_DEPTH'] = 4096
|
parameters['FIFO_DEPTH'] = 4096
|
||||||
parameters['CMD_FIFO_DEPTH'] = 32
|
parameters['CMD_FIFO_DEPTH'] = 32
|
||||||
parameters['SPEEDUP'] = 0
|
parameters['SPEEDUP'] = 0
|
||||||
@ -335,20 +361,26 @@ def test_axis_ram_switch(request, s_count, m_count, s_data_width, m_data_width):
|
|||||||
parameters['M_KEEP_ENABLE'] = int(parameters['M_DATA_WIDTH'] > 8)
|
parameters['M_KEEP_ENABLE'] = int(parameters['M_DATA_WIDTH'] > 8)
|
||||||
parameters['M_KEEP_WIDTH'] = parameters['M_DATA_WIDTH'] // 8
|
parameters['M_KEEP_WIDTH'] = parameters['M_DATA_WIDTH'] // 8
|
||||||
parameters['ID_ENABLE'] = 1
|
parameters['ID_ENABLE'] = 1
|
||||||
parameters['ID_WIDTH'] = 16
|
parameters['S_ID_WIDTH'] = 16
|
||||||
parameters['DEST_WIDTH'] = 8
|
parameters['M_ID_WIDTH'] = parameters['S_ID_WIDTH'] + (s_count-1).bit_length()
|
||||||
|
parameters['M_DEST_WIDTH'] = 8
|
||||||
|
parameters['S_DEST_WIDTH'] = parameters['M_DEST_WIDTH'] + (m_count-1).bit_length()
|
||||||
parameters['USER_ENABLE'] = 1
|
parameters['USER_ENABLE'] = 1
|
||||||
parameters['USER_WIDTH'] = 1
|
parameters['USER_WIDTH'] = 1
|
||||||
parameters['USER_BAD_FRAME_VALUE'] = 1
|
parameters['USER_BAD_FRAME_VALUE'] = 1
|
||||||
parameters['USER_BAD_FRAME_MASK'] = 1
|
parameters['USER_BAD_FRAME_MASK'] = 1
|
||||||
parameters['DROP_BAD_FRAME'] = 0
|
parameters['DROP_BAD_FRAME'] = 0
|
||||||
parameters['DROP_WHEN_FULL'] = 0
|
parameters['DROP_WHEN_FULL'] = 0
|
||||||
|
parameters['UPDATE_TID'] = 1
|
||||||
parameters['ARB_TYPE_ROUND_ROBIN'] = 1
|
parameters['ARB_TYPE_ROUND_ROBIN'] = 1
|
||||||
parameters['ARB_LSB_HIGH_PRIORITY'] = 1
|
parameters['ARB_LSB_HIGH_PRIORITY'] = 1
|
||||||
parameters['RAM_PIPELINE'] = 2
|
parameters['RAM_PIPELINE'] = 2
|
||||||
|
|
||||||
extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()}
|
extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()}
|
||||||
|
|
||||||
|
extra_env['S_COUNT'] = str(s_count)
|
||||||
|
extra_env['M_COUNT'] = str(m_count)
|
||||||
|
|
||||||
sim_build = os.path.join(tests_dir, "sim_build",
|
sim_build = os.path.join(tests_dir, "sim_build",
|
||||||
request.node.name.replace('[', '-').replace(']', ''))
|
request.node.name.replace('[', '-').replace(']', ''))
|
||||||
|
|
||||||
|
@ -66,10 +66,10 @@ class TB(object):
|
|||||||
self.dut.rst.setimmediatevalue(0)
|
self.dut.rst.setimmediatevalue(0)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
self.dut.rst <= 1
|
self.dut.rst.value = 1
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
self.dut.rst <= 0
|
self.dut.rst.value = 0
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
|
|
||||||
@ -87,8 +87,8 @@ async def run_test(dut, payload_lengths=None, payload_data=None, idle_inserter=N
|
|||||||
tb.set_idle_generator(idle_inserter)
|
tb.set_idle_generator(idle_inserter)
|
||||||
tb.set_backpressure_generator(backpressure_inserter)
|
tb.set_backpressure_generator(backpressure_inserter)
|
||||||
|
|
||||||
dut.rate_num <= rate[0]
|
dut.rate_num.value = rate[0]
|
||||||
dut.rate_denom <= rate[1]
|
dut.rate_denom.value = rate[1]
|
||||||
await RisingEdge(dut.clk)
|
await RisingEdge(dut.clk)
|
||||||
|
|
||||||
test_frames = []
|
test_frames = []
|
||||||
|
@ -63,10 +63,10 @@ class TB(object):
|
|||||||
self.dut.rst.setimmediatevalue(0)
|
self.dut.rst.setimmediatevalue(0)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
self.dut.rst <= 1
|
self.dut.rst.value = 1
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
self.dut.rst <= 0
|
self.dut.rst.value = 0
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
|
|
||||||
|
@ -63,10 +63,10 @@ class TB(object):
|
|||||||
self.dut.rst.setimmediatevalue(0)
|
self.dut.rst.setimmediatevalue(0)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
self.dut.rst <= 1
|
self.dut.rst.value = 1
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
self.dut.rst <= 0
|
self.dut.rst.value = 0
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
|
|
||||||
|
@ -63,10 +63,10 @@ class TB(object):
|
|||||||
self.dut.rst.setimmediatevalue(0)
|
self.dut.rst.setimmediatevalue(0)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
self.dut.rst <= 1
|
self.dut.rst.value = 1
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
self.dut.rst <= 0
|
self.dut.rst.value = 0
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
|
|
||||||
|
@ -26,11 +26,11 @@ WAVES ?= 0
|
|||||||
COCOTB_HDL_TIMEUNIT = 1ns
|
COCOTB_HDL_TIMEUNIT = 1ns
|
||||||
COCOTB_HDL_TIMEPRECISION = 1ps
|
COCOTB_HDL_TIMEPRECISION = 1ps
|
||||||
|
|
||||||
export PARAM_S_COUNT ?= 4
|
export S_COUNT ?= 4
|
||||||
export PARAM_M_COUNT ?= 4
|
export M_COUNT ?= 4
|
||||||
|
|
||||||
DUT = axis_switch
|
DUT = axis_switch
|
||||||
WRAPPER = $(DUT)_wrap_$(PARAM_S_COUNT)x$(PARAM_M_COUNT)
|
WRAPPER = $(DUT)_wrap_$(S_COUNT)x$(M_COUNT)
|
||||||
TOPLEVEL = $(WRAPPER)
|
TOPLEVEL = $(WRAPPER)
|
||||||
MODULE = test_$(DUT)
|
MODULE = test_$(DUT)
|
||||||
VERILOG_SOURCES += $(WRAPPER).v
|
VERILOG_SOURCES += $(WRAPPER).v
|
||||||
@ -44,10 +44,13 @@ export PARAM_DATA_WIDTH ?= 8
|
|||||||
export PARAM_KEEP_ENABLE ?= $(shell expr $(PARAM_DATA_WIDTH) \> 8 )
|
export PARAM_KEEP_ENABLE ?= $(shell expr $(PARAM_DATA_WIDTH) \> 8 )
|
||||||
export PARAM_KEEP_WIDTH ?= $(shell expr $(PARAM_DATA_WIDTH) / 8 )
|
export PARAM_KEEP_WIDTH ?= $(shell expr $(PARAM_DATA_WIDTH) / 8 )
|
||||||
export PARAM_ID_ENABLE ?= 1
|
export PARAM_ID_ENABLE ?= 1
|
||||||
export PARAM_ID_WIDTH ?= 16
|
export PARAM_S_ID_WIDTH ?= 16
|
||||||
export PARAM_DEST_WIDTH ?= 8
|
export PARAM_M_ID_WIDTH ?= $(shell python -c "print($(PARAM_S_ID_WIDTH) + ($(S_COUNT)-1).bit_length())")
|
||||||
|
export PARAM_M_DEST_WIDTH ?= 8
|
||||||
|
export PARAM_S_DEST_WIDTH ?= $(shell python -c "print($(PARAM_M_DEST_WIDTH) + ($(M_COUNT)-1).bit_length())")
|
||||||
export PARAM_USER_ENABLE ?= 1
|
export PARAM_USER_ENABLE ?= 1
|
||||||
export PARAM_USER_WIDTH ?= 1
|
export PARAM_USER_WIDTH ?= 1
|
||||||
|
export PARAM_UPDATE_TID ?= 1
|
||||||
export PARAM_S_REG_TYPE ?= 0
|
export PARAM_S_REG_TYPE ?= 0
|
||||||
export PARAM_M_REG_TYPE ?= 2
|
export PARAM_M_REG_TYPE ?= 2
|
||||||
export PARAM_ARB_TYPE_ROUND_ROBIN ?= 1
|
export PARAM_ARB_TYPE_ROUND_ROBIN ?= 1
|
||||||
@ -60,10 +63,13 @@ ifeq ($(SIM), icarus)
|
|||||||
COMPILE_ARGS += -P $(TOPLEVEL).KEEP_ENABLE=$(PARAM_KEEP_ENABLE)
|
COMPILE_ARGS += -P $(TOPLEVEL).KEEP_ENABLE=$(PARAM_KEEP_ENABLE)
|
||||||
COMPILE_ARGS += -P $(TOPLEVEL).KEEP_WIDTH=$(PARAM_KEEP_WIDTH)
|
COMPILE_ARGS += -P $(TOPLEVEL).KEEP_WIDTH=$(PARAM_KEEP_WIDTH)
|
||||||
COMPILE_ARGS += -P $(TOPLEVEL).ID_ENABLE=$(PARAM_ID_ENABLE)
|
COMPILE_ARGS += -P $(TOPLEVEL).ID_ENABLE=$(PARAM_ID_ENABLE)
|
||||||
COMPILE_ARGS += -P $(TOPLEVEL).ID_WIDTH=$(PARAM_ID_WIDTH)
|
COMPILE_ARGS += -P $(TOPLEVEL).S_ID_WIDTH=$(PARAM_S_ID_WIDTH)
|
||||||
COMPILE_ARGS += -P $(TOPLEVEL).DEST_WIDTH=$(PARAM_DEST_WIDTH)
|
COMPILE_ARGS += -P $(TOPLEVEL).M_ID_WIDTH=$(PARAM_M_ID_WIDTH)
|
||||||
|
COMPILE_ARGS += -P $(TOPLEVEL).S_DEST_WIDTH=$(PARAM_S_DEST_WIDTH)
|
||||||
|
COMPILE_ARGS += -P $(TOPLEVEL).M_DEST_WIDTH=$(PARAM_M_DEST_WIDTH)
|
||||||
COMPILE_ARGS += -P $(TOPLEVEL).USER_ENABLE=$(PARAM_USER_ENABLE)
|
COMPILE_ARGS += -P $(TOPLEVEL).USER_ENABLE=$(PARAM_USER_ENABLE)
|
||||||
COMPILE_ARGS += -P $(TOPLEVEL).USER_WIDTH=$(PARAM_USER_WIDTH)
|
COMPILE_ARGS += -P $(TOPLEVEL).USER_WIDTH=$(PARAM_USER_WIDTH)
|
||||||
|
COMPILE_ARGS += -P $(TOPLEVEL).UPDATE_TID=$(PARAM_UPDATE_TID)
|
||||||
COMPILE_ARGS += -P $(TOPLEVEL).S_REG_TYPE=$(PARAM_S_REG_TYPE)
|
COMPILE_ARGS += -P $(TOPLEVEL).S_REG_TYPE=$(PARAM_S_REG_TYPE)
|
||||||
COMPILE_ARGS += -P $(TOPLEVEL).M_REG_TYPE=$(PARAM_M_REG_TYPE)
|
COMPILE_ARGS += -P $(TOPLEVEL).M_REG_TYPE=$(PARAM_M_REG_TYPE)
|
||||||
COMPILE_ARGS += -P $(TOPLEVEL).ARB_TYPE_ROUND_ROBIN=$(PARAM_ARB_TYPE_ROUND_ROBIN)
|
COMPILE_ARGS += -P $(TOPLEVEL).ARB_TYPE_ROUND_ROBIN=$(PARAM_ARB_TYPE_ROUND_ROBIN)
|
||||||
@ -80,10 +86,13 @@ else ifeq ($(SIM), verilator)
|
|||||||
COMPILE_ARGS += -GKEEP_ENABLE=$(PARAM_KEEP_ENABLE)
|
COMPILE_ARGS += -GKEEP_ENABLE=$(PARAM_KEEP_ENABLE)
|
||||||
COMPILE_ARGS += -GKEEP_WIDTH=$(PARAM_KEEP_WIDTH)
|
COMPILE_ARGS += -GKEEP_WIDTH=$(PARAM_KEEP_WIDTH)
|
||||||
COMPILE_ARGS += -GID_ENABLE=$(PARAM_ID_ENABLE)
|
COMPILE_ARGS += -GID_ENABLE=$(PARAM_ID_ENABLE)
|
||||||
COMPILE_ARGS += -GID_WIDTH=$(PARAM_ID_WIDTH)
|
COMPILE_ARGS += -GS_ID_WIDTH=$(PARAM_S_ID_WIDTH)
|
||||||
COMPILE_ARGS += -GDEST_WIDTH=$(PARAM_DEST_WIDTH)
|
COMPILE_ARGS += -GM_ID_WIDTH=$(PARAM_M_ID_WIDTH)
|
||||||
|
COMPILE_ARGS += -GS_DEST_WIDTH=$(PARAM_S_DEST_WIDTH)
|
||||||
|
COMPILE_ARGS += -GM_DEST_WIDTH=$(PARAM_M_DEST_WIDTH)
|
||||||
COMPILE_ARGS += -GUSER_ENABLE=$(PARAM_USER_ENABLE)
|
COMPILE_ARGS += -GUSER_ENABLE=$(PARAM_USER_ENABLE)
|
||||||
COMPILE_ARGS += -GUSER_WIDTH=$(PARAM_USER_WIDTH)
|
COMPILE_ARGS += -GUSER_WIDTH=$(PARAM_USER_WIDTH)
|
||||||
|
COMPILE_ARGS += -GUPDATE_TID=$(PARAM_UPDATE_TID)
|
||||||
COMPILE_ARGS += -GS_REG_TYPE=$(PARAM_S_REG_TYPE)
|
COMPILE_ARGS += -GS_REG_TYPE=$(PARAM_S_REG_TYPE)
|
||||||
COMPILE_ARGS += -GM_REG_TYPE=$(PARAM_M_REG_TYPE)
|
COMPILE_ARGS += -GM_REG_TYPE=$(PARAM_M_REG_TYPE)
|
||||||
COMPILE_ARGS += -GARB_TYPE_ROUND_ROBIN=$(PARAM_ARB_TYPE_ROUND_ROBIN)
|
COMPILE_ARGS += -GARB_TYPE_ROUND_ROBIN=$(PARAM_ARB_TYPE_ROUND_ROBIN)
|
||||||
@ -97,7 +106,7 @@ endif
|
|||||||
include $(shell cocotb-config --makefiles)/Makefile.sim
|
include $(shell cocotb-config --makefiles)/Makefile.sim
|
||||||
|
|
||||||
$(WRAPPER).v: ../../rtl/$(DUT)_wrap.py
|
$(WRAPPER).v: ../../rtl/$(DUT)_wrap.py
|
||||||
$< -p $(PARAM_S_COUNT) $(PARAM_M_COUNT)
|
$< -p $(S_COUNT) $(M_COUNT)
|
||||||
|
|
||||||
iverilog_dump.v:
|
iverilog_dump.v:
|
||||||
echo 'module iverilog_dump();' > $@
|
echo 'module iverilog_dump();' > $@
|
||||||
|
@ -69,10 +69,10 @@ class TB(object):
|
|||||||
self.dut.rst.setimmediatevalue(0)
|
self.dut.rst.setimmediatevalue(0)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
self.dut.rst <= 1
|
self.dut.rst.value = 1
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
self.dut.rst <= 0
|
self.dut.rst.value = 0
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
await RisingEdge(self.dut.clk)
|
await RisingEdge(self.dut.clk)
|
||||||
|
|
||||||
@ -81,7 +81,15 @@ async def run_test(dut, payload_lengths=None, payload_data=None, idle_inserter=N
|
|||||||
|
|
||||||
tb = TB(dut)
|
tb = TB(dut)
|
||||||
|
|
||||||
id_count = 2**len(tb.source[s].bus.tid)
|
id_width = len(tb.source[0].bus.tid)
|
||||||
|
id_count = 2**id_width
|
||||||
|
id_mask = id_count-1
|
||||||
|
|
||||||
|
src_width = (len(tb.source)-1).bit_length()
|
||||||
|
src_mask = 2**src_width-1 if src_width else 0
|
||||||
|
src_shift = id_width-src_width
|
||||||
|
max_count = 2**src_shift
|
||||||
|
count_mask = max_count-1
|
||||||
|
|
||||||
cur_id = 1
|
cur_id = 1
|
||||||
|
|
||||||
@ -94,19 +102,21 @@ async def run_test(dut, payload_lengths=None, payload_data=None, idle_inserter=N
|
|||||||
|
|
||||||
for test_data in [payload_data(x) for x in payload_lengths()]:
|
for test_data in [payload_data(x) for x in payload_lengths()]:
|
||||||
test_frame = AxiStreamFrame(test_data)
|
test_frame = AxiStreamFrame(test_data)
|
||||||
test_frame.tid = cur_id
|
test_frame.tid = cur_id | (s << src_shift)
|
||||||
test_frame.tdest = m
|
test_frame.tdest = m
|
||||||
|
|
||||||
test_frames.append(test_frame)
|
test_frames.append(test_frame)
|
||||||
await tb.source[s].send(test_frame)
|
await tb.source[s].send(test_frame)
|
||||||
|
|
||||||
cur_id = (cur_id + 1) % id_count
|
cur_id = (cur_id + 1) % max_count
|
||||||
|
|
||||||
for test_frame in test_frames:
|
for test_frame in test_frames:
|
||||||
rx_frame = await tb.sink[m].recv()
|
rx_frame = await tb.sink[m].recv()
|
||||||
|
|
||||||
assert rx_frame.tdata == test_frame.tdata
|
assert rx_frame.tdata == test_frame.tdata
|
||||||
assert rx_frame.tid == test_frame.tid
|
assert (rx_frame.tid & id_mask) == test_frame.tid
|
||||||
|
assert ((rx_frame.tid >> src_shift) & src_mask) == s
|
||||||
|
assert (rx_frame.tid >> id_width) == s
|
||||||
assert rx_frame.tdest == test_frame.tdest
|
assert rx_frame.tdest == test_frame.tdest
|
||||||
assert not rx_frame.tuser
|
assert not rx_frame.tuser
|
||||||
|
|
||||||
@ -142,7 +152,15 @@ async def run_arb_test(dut):
|
|||||||
tb = TB(dut)
|
tb = TB(dut)
|
||||||
|
|
||||||
byte_lanes = tb.source[0].byte_lanes
|
byte_lanes = tb.source[0].byte_lanes
|
||||||
id_count = 2**len(tb.source[0].bus.tid)
|
id_width = len(tb.source[0].bus.tid)
|
||||||
|
id_count = 2**id_width
|
||||||
|
id_mask = id_count-1
|
||||||
|
|
||||||
|
src_width = (len(tb.source)-1).bit_length()
|
||||||
|
src_mask = 2**src_width-1 if src_width else 0
|
||||||
|
src_shift = id_width-src_width
|
||||||
|
max_count = 2**src_shift
|
||||||
|
count_mask = max_count-1
|
||||||
|
|
||||||
cur_id = 1
|
cur_id = 1
|
||||||
|
|
||||||
@ -155,8 +173,6 @@ async def run_arb_test(dut):
|
|||||||
|
|
||||||
for k in range(5):
|
for k in range(5):
|
||||||
test_frame = AxiStreamFrame(test_data, tx_complete=Event())
|
test_frame = AxiStreamFrame(test_data, tx_complete=Event())
|
||||||
test_frame.tid = cur_id
|
|
||||||
test_frame.tdest = 0
|
|
||||||
|
|
||||||
src_ind = 0
|
src_ind = 0
|
||||||
|
|
||||||
@ -170,17 +186,21 @@ async def run_arb_test(dut):
|
|||||||
else:
|
else:
|
||||||
src_ind = 1
|
src_ind = 1
|
||||||
|
|
||||||
|
test_frame.tid = cur_id | (src_ind << src_shift)
|
||||||
|
test_frame.tdest = 0
|
||||||
|
|
||||||
test_frames.append(test_frame)
|
test_frames.append(test_frame)
|
||||||
await tb.source[src_ind].send(test_frame)
|
await tb.source[src_ind].send(test_frame)
|
||||||
|
|
||||||
cur_id = (cur_id + 1) % id_count
|
cur_id = (cur_id + 1) % max_count
|
||||||
|
|
||||||
for k in [0, 1, 2, 4, 3]:
|
for k in [0, 1, 2, 4, 3]:
|
||||||
test_frame = test_frames[k]
|
test_frame = test_frames[k]
|
||||||
rx_frame = await tb.sink[0].recv()
|
rx_frame = await tb.sink[0].recv()
|
||||||
|
|
||||||
assert rx_frame.tdata == test_frame.tdata
|
assert rx_frame.tdata == test_frame.tdata
|
||||||
assert rx_frame.tid == test_frame.tid
|
assert (rx_frame.tid & id_mask) == test_frame.tid
|
||||||
|
assert ((rx_frame.tid >> src_shift) & src_mask) == (rx_frame.tid >> id_width)
|
||||||
assert rx_frame.tdest == test_frame.tdest
|
assert rx_frame.tdest == test_frame.tdest
|
||||||
assert not rx_frame.tuser
|
assert not rx_frame.tuser
|
||||||
|
|
||||||
@ -195,7 +215,15 @@ async def run_stress_test(dut, idle_inserter=None, backpressure_inserter=None):
|
|||||||
tb = TB(dut)
|
tb = TB(dut)
|
||||||
|
|
||||||
byte_lanes = tb.source[0].byte_lanes
|
byte_lanes = tb.source[0].byte_lanes
|
||||||
id_count = 2**len(tb.source[0].bus.tid)
|
id_width = len(tb.source[0].bus.tid)
|
||||||
|
id_count = 2**id_width
|
||||||
|
id_mask = id_count-1
|
||||||
|
|
||||||
|
src_width = (len(tb.source)-1).bit_length()
|
||||||
|
src_mask = 2**src_width-1 if src_width else 0
|
||||||
|
src_shift = id_width-src_width
|
||||||
|
max_count = 2**src_shift
|
||||||
|
count_mask = max_count-1
|
||||||
|
|
||||||
cur_id = 1
|
cur_id = 1
|
||||||
|
|
||||||
@ -211,13 +239,13 @@ async def run_stress_test(dut, idle_inserter=None, backpressure_inserter=None):
|
|||||||
length = random.randint(1, byte_lanes*16)
|
length = random.randint(1, byte_lanes*16)
|
||||||
test_data = bytearray(itertools.islice(itertools.cycle(range(256)), length))
|
test_data = bytearray(itertools.islice(itertools.cycle(range(256)), length))
|
||||||
test_frame = AxiStreamFrame(test_data)
|
test_frame = AxiStreamFrame(test_data)
|
||||||
test_frame.tid = cur_id
|
test_frame.tid = cur_id | (p << src_shift)
|
||||||
test_frame.tdest = random.randrange(len(tb.sink))
|
test_frame.tdest = random.randrange(len(tb.sink))
|
||||||
|
|
||||||
test_frames[p][test_frame.tdest].append(test_frame)
|
test_frames[p][test_frame.tdest].append(test_frame)
|
||||||
await tb.source[p].send(test_frame)
|
await tb.source[p].send(test_frame)
|
||||||
|
|
||||||
cur_id = (cur_id + 1) % id_count
|
cur_id = (cur_id + 1) % max_count
|
||||||
|
|
||||||
for lst in test_frames:
|
for lst in test_frames:
|
||||||
while any(lst):
|
while any(lst):
|
||||||
@ -227,15 +255,15 @@ async def run_stress_test(dut, idle_inserter=None, backpressure_inserter=None):
|
|||||||
|
|
||||||
for lst_a in test_frames:
|
for lst_a in test_frames:
|
||||||
for lst_b in lst_a:
|
for lst_b in lst_a:
|
||||||
if lst_b and lst_b[0].tid == rx_frame.tid:
|
if lst_b and lst_b[0].tid == (rx_frame.tid & id_mask):
|
||||||
test_frame = lst_b.pop(0)
|
test_frame = lst_b.pop(0)
|
||||||
break
|
break
|
||||||
|
|
||||||
assert test_frame is not None
|
assert test_frame is not None
|
||||||
|
|
||||||
assert rx_frame.tdata == test_frame.tdata
|
assert rx_frame.tdata == test_frame.tdata
|
||||||
assert rx_frame.tid == test_frame.tid
|
assert (rx_frame.tid & id_mask) == test_frame.tid
|
||||||
assert rx_frame.tdest == test_frame.tdest
|
assert ((rx_frame.tid >> src_shift) & src_mask) == (rx_frame.tid >> id_width)
|
||||||
assert not rx_frame.tuser
|
assert not rx_frame.tuser
|
||||||
|
|
||||||
assert all(s.empty() for s in tb.sink)
|
assert all(s.empty() for s in tb.sink)
|
||||||
@ -321,17 +349,17 @@ def test_axis_switch(request, s_count, m_count, data_width):
|
|||||||
|
|
||||||
parameters = {}
|
parameters = {}
|
||||||
|
|
||||||
parameters['S_COUNT'] = s_count
|
|
||||||
parameters['M_COUNT'] = m_count
|
|
||||||
|
|
||||||
parameters['DATA_WIDTH'] = data_width
|
parameters['DATA_WIDTH'] = data_width
|
||||||
parameters['KEEP_ENABLE'] = int(parameters['DATA_WIDTH'] > 8)
|
parameters['KEEP_ENABLE'] = int(parameters['DATA_WIDTH'] > 8)
|
||||||
parameters['KEEP_WIDTH'] = parameters['DATA_WIDTH'] // 8
|
parameters['KEEP_WIDTH'] = parameters['DATA_WIDTH'] // 8
|
||||||
parameters['ID_ENABLE'] = 1
|
parameters['ID_ENABLE'] = 1
|
||||||
parameters['ID_WIDTH'] = 16
|
parameters['S_ID_WIDTH'] = 16
|
||||||
parameters['DEST_WIDTH'] = 8
|
parameters['M_ID_WIDTH'] = parameters['S_ID_WIDTH'] + (s_count-1).bit_length()
|
||||||
|
parameters['M_DEST_WIDTH'] = 8
|
||||||
|
parameters['S_DEST_WIDTH'] = parameters['M_DEST_WIDTH'] + (m_count-1).bit_length()
|
||||||
parameters['USER_ENABLE'] = 1
|
parameters['USER_ENABLE'] = 1
|
||||||
parameters['USER_WIDTH'] = 1
|
parameters['USER_WIDTH'] = 1
|
||||||
|
parameters['UPDATE_TID'] = 1
|
||||||
parameters['S_REG_TYPE'] = 0
|
parameters['S_REG_TYPE'] = 0
|
||||||
parameters['M_REG_TYPE'] = 2
|
parameters['M_REG_TYPE'] = 2
|
||||||
parameters['ARB_TYPE_ROUND_ROBIN'] = 1
|
parameters['ARB_TYPE_ROUND_ROBIN'] = 1
|
||||||
@ -339,6 +367,9 @@ def test_axis_switch(request, s_count, m_count, data_width):
|
|||||||
|
|
||||||
extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()}
|
extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()}
|
||||||
|
|
||||||
|
extra_env['S_COUNT'] = str(s_count)
|
||||||
|
extra_env['M_COUNT'] = str(m_count)
|
||||||
|
|
||||||
sim_build = os.path.join(tests_dir, "sim_build",
|
sim_build = os.path.join(tests_dir, "sim_build",
|
||||||
request.node.name.replace('[', '-').replace(']', ''))
|
request.node.name.replace('[', '-').replace(']', ''))
|
||||||
|
|
||||||
|
@ -30,36 +30,11 @@ from cocotb.triggers import RisingEdge, Timer, First, Event
|
|||||||
from cocotb.utils import get_sim_time
|
from cocotb.utils import get_sim_time
|
||||||
|
|
||||||
from cocotbext.eth.constants import (EthPre, XgmiiCtrl, BaseRCtrl, BaseRO,
|
from cocotbext.eth.constants import (EthPre, XgmiiCtrl, BaseRCtrl, BaseRO,
|
||||||
BaseRSync, BaseRBlockType)
|
BaseRSync, BaseRBlockType, xgmii_ctrl_to_baser_mapping,
|
||||||
|
baser_ctrl_to_xgmii_mapping, block_type_term_lane_mapping)
|
||||||
from cocotbext.eth import XgmiiFrame
|
from cocotbext.eth import XgmiiFrame
|
||||||
|
|
||||||
|
|
||||||
xgmii_ctrl_to_baser_mapping = {
|
|
||||||
XgmiiCtrl.IDLE: BaseRCtrl.IDLE,
|
|
||||||
XgmiiCtrl.LPI: BaseRCtrl.LPI,
|
|
||||||
XgmiiCtrl.ERROR: BaseRCtrl.ERROR,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
baser_ctrl_to_xgmii_mapping = {
|
|
||||||
BaseRCtrl.IDLE: XgmiiCtrl.IDLE,
|
|
||||||
BaseRCtrl.LPI: XgmiiCtrl.LPI,
|
|
||||||
BaseRCtrl.ERROR: XgmiiCtrl.ERROR,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
block_type_term_lane_mapping = {
|
|
||||||
BaseRBlockType.TERM_0: 0,
|
|
||||||
BaseRBlockType.TERM_1: 1,
|
|
||||||
BaseRBlockType.TERM_2: 2,
|
|
||||||
BaseRBlockType.TERM_3: 3,
|
|
||||||
BaseRBlockType.TERM_4: 4,
|
|
||||||
BaseRBlockType.TERM_5: 5,
|
|
||||||
BaseRBlockType.TERM_6: 6,
|
|
||||||
BaseRBlockType.TERM_7: 7,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class BaseRSerdesSource():
|
class BaseRSerdesSource():
|
||||||
|
|
||||||
def __init__(self, data, header, clock, enable=None, slip=None, scramble=True, reverse=False, *args, **kwargs):
|
def __init__(self, data, header, clock, enable=None, slip=None, scramble=True, reverse=False, *args, **kwargs):
|
||||||
@ -271,7 +246,7 @@ class BaseRSerdesSource():
|
|||||||
if cl[0] and (dl[0] == XgmiiCtrl.SEQ_OS or dl[0] == XgmiiCtrl.SIG_OS) and not any(cl[1:4]):
|
if cl[0] and (dl[0] == XgmiiCtrl.SEQ_OS or dl[0] == XgmiiCtrl.SIG_OS) and not any(cl[1:4]):
|
||||||
# ordered set in lane 0
|
# ordered set in lane 0
|
||||||
data = BaseRBlockType.OS_START
|
data = BaseRBlockType.OS_START
|
||||||
for i in range(1,4):
|
for i in range(1, 4):
|
||||||
data |= dl[i] << i*8
|
data |= dl[i] << i*8
|
||||||
if dl[0] == XgmiiCtrl.SIG_OS:
|
if dl[0] == XgmiiCtrl.SIG_OS:
|
||||||
# signal ordered set
|
# signal ordered set
|
||||||
@ -287,7 +262,7 @@ class BaseRSerdesSource():
|
|||||||
if cl[4] and (dl[4] == XgmiiCtrl.SEQ_OS or dl[4] == XgmiiCtrl.SIG_OS) and not any(cl[5:8]):
|
if cl[4] and (dl[4] == XgmiiCtrl.SEQ_OS or dl[4] == XgmiiCtrl.SIG_OS) and not any(cl[5:8]):
|
||||||
# ordered set in lane 4
|
# ordered set in lane 4
|
||||||
data = BaseRBlockType.OS_04
|
data = BaseRBlockType.OS_04
|
||||||
for i in range(5,8):
|
for i in range(5, 8):
|
||||||
data |= dl[i] << i*8
|
data |= dl[i] << i*8
|
||||||
if dl[4] == XgmiiCtrl.SIG_OS:
|
if dl[4] == XgmiiCtrl.SIG_OS:
|
||||||
# signal ordered set
|
# signal ordered set
|
||||||
|
Loading…
x
Reference in New Issue
Block a user