1
0
mirror of https://github.com/corundum/corundum.git synced 2025-01-16 08:12:53 +08:00

Consolidate, add configuration parameters, and add tid and tdest ports to AXI stream adapter

This commit is contained in:
Alex Forencich 2017-11-20 20:12:43 -08:00
parent fdb881719c
commit d50c767482
5 changed files with 321 additions and 133 deletions

View File

@ -32,9 +32,17 @@ THE SOFTWARE.
module axis_adapter #
(
parameter INPUT_DATA_WIDTH = 8,
parameter INPUT_KEEP_ENABLE = (INPUT_DATA_WIDTH>8),
parameter INPUT_KEEP_WIDTH = (INPUT_DATA_WIDTH/8),
parameter OUTPUT_DATA_WIDTH = 8,
parameter OUTPUT_KEEP_WIDTH = (OUTPUT_DATA_WIDTH/8)
parameter OUTPUT_KEEP_ENABLE = (OUTPUT_DATA_WIDTH>8),
parameter OUTPUT_KEEP_WIDTH = (OUTPUT_DATA_WIDTH/8),
parameter ID_ENABLE = 0,
parameter ID_WIDTH = 8,
parameter DEST_ENABLE = 0,
parameter DEST_WIDTH = 8,
parameter USER_ENABLE = 1,
parameter USER_WIDTH = 1
)
(
input wire clk,
@ -48,7 +56,9 @@ module axis_adapter #
input wire input_axis_tvalid,
output wire input_axis_tready,
input wire input_axis_tlast,
input wire input_axis_tuser,
input wire [ID_WIDTH-1:0] input_axis_tid,
input wire [DEST_WIDTH-1:0] input_axis_tdest,
input wire [USER_WIDTH-1:0] input_axis_tuser,
/*
* AXI output
@ -58,31 +68,37 @@ module axis_adapter #
output wire output_axis_tvalid,
input wire output_axis_tready,
output wire output_axis_tlast,
output wire output_axis_tuser
output wire [ID_WIDTH-1:0] output_axis_tid,
output wire [DEST_WIDTH-1:0] output_axis_tdest,
output wire [USER_WIDTH-1:0] output_axis_tuser
);
// force keep width to 1 when disabled
localparam INPUT_KEEP_WIDTH_INT = INPUT_KEEP_ENABLE ? INPUT_KEEP_WIDTH : 1;
localparam OUTPUT_KEEP_WIDTH_INT = OUTPUT_KEEP_ENABLE ? OUTPUT_KEEP_WIDTH : 1;
// bus word sizes (must be identical)
localparam INPUT_DATA_WORD_SIZE = INPUT_DATA_WIDTH / INPUT_KEEP_WIDTH;
localparam OUTPUT_DATA_WORD_SIZE = OUTPUT_DATA_WIDTH / OUTPUT_KEEP_WIDTH;
localparam INPUT_DATA_WORD_SIZE = INPUT_DATA_WIDTH / INPUT_KEEP_WIDTH_INT;
localparam OUTPUT_DATA_WORD_SIZE = OUTPUT_DATA_WIDTH / OUTPUT_KEEP_WIDTH_INT;
// output bus is wider
localparam EXPAND_BUS = OUTPUT_KEEP_WIDTH > INPUT_KEEP_WIDTH;
localparam EXPAND_BUS = OUTPUT_KEEP_WIDTH_INT > INPUT_KEEP_WIDTH_INT;
// total data and keep widths
localparam DATA_WIDTH = EXPAND_BUS ? OUTPUT_DATA_WIDTH : INPUT_DATA_WIDTH;
localparam KEEP_WIDTH = EXPAND_BUS ? OUTPUT_KEEP_WIDTH : INPUT_KEEP_WIDTH;
localparam KEEP_WIDTH = EXPAND_BUS ? OUTPUT_KEEP_WIDTH_INT : INPUT_KEEP_WIDTH_INT;
// required number of cycles to match widths
localparam CYCLE_COUNT = EXPAND_BUS ? (OUTPUT_KEEP_WIDTH / INPUT_KEEP_WIDTH) : (INPUT_KEEP_WIDTH / OUTPUT_KEEP_WIDTH);
localparam CYCLE_COUNT = EXPAND_BUS ? (OUTPUT_KEEP_WIDTH_INT / INPUT_KEEP_WIDTH_INT) : (INPUT_KEEP_WIDTH_INT / OUTPUT_KEEP_WIDTH_INT);
// data width and keep width per cycle
localparam CYCLE_DATA_WIDTH = DATA_WIDTH / CYCLE_COUNT;
localparam CYCLE_KEEP_WIDTH = KEEP_WIDTH / CYCLE_COUNT;
// bus width assertions
initial begin
if (INPUT_DATA_WORD_SIZE * INPUT_KEEP_WIDTH != INPUT_DATA_WIDTH) begin
if (INPUT_DATA_WORD_SIZE * INPUT_KEEP_WIDTH_INT != INPUT_DATA_WIDTH) begin
$error("Error: input data width not evenly divisble");
$finish;
end
if (OUTPUT_DATA_WORD_SIZE * OUTPUT_KEEP_WIDTH != OUTPUT_DATA_WIDTH) begin
if (OUTPUT_DATA_WORD_SIZE * OUTPUT_KEEP_WIDTH_INT != OUTPUT_DATA_WIDTH) begin
$error("Error: output data width not evenly divisble");
$finish;
end
@ -108,16 +124,20 @@ reg last_cycle;
reg [DATA_WIDTH-1:0] temp_tdata_reg = {DATA_WIDTH{1'b0}}, temp_tdata_next;
reg [KEEP_WIDTH-1:0] temp_tkeep_reg = {KEEP_WIDTH{1'b0}}, temp_tkeep_next;
reg temp_tlast_reg = 1'b0, temp_tlast_next;
reg temp_tuser_reg = 1'b0, temp_tuser_next;
reg [ID_WIDTH-1:0] temp_tid_reg = {ID_WIDTH{1'b0}}, temp_tid_next;
reg [DEST_WIDTH-1:0] temp_tdest_reg = {DEST_WIDTH{1'b0}}, temp_tdest_next;
reg [USER_WIDTH-1:0] temp_tuser_reg = {USER_WIDTH{1'b0}}, temp_tuser_next;
// internal datapath
reg [OUTPUT_DATA_WIDTH-1:0] output_axis_tdata_int;
reg [OUTPUT_KEEP_WIDTH-1:0] output_axis_tkeep_int;
reg output_axis_tvalid_int;
reg output_axis_tready_int_reg = 1'b0;
reg output_axis_tlast_int;
reg output_axis_tuser_int;
wire output_axis_tready_int_early;
reg [OUTPUT_DATA_WIDTH-1:0] output_axis_tdata_int;
reg [OUTPUT_KEEP_WIDTH-1:0] output_axis_tkeep_int;
reg output_axis_tvalid_int;
reg output_axis_tready_int_reg = 1'b0;
reg output_axis_tlast_int;
reg [ID_WIDTH-1:0] output_axis_tid_int;
reg [DEST_WIDTH-1:0] output_axis_tdest_int;
reg [USER_WIDTH-1:0] output_axis_tuser_int;
wire output_axis_tready_int_early;
reg input_axis_tready_reg = 1'b0, input_axis_tready_next;
@ -131,13 +151,17 @@ always @* begin
temp_tdata_next = temp_tdata_reg;
temp_tkeep_next = temp_tkeep_reg;
temp_tlast_next = temp_tlast_reg;
temp_tid_next = temp_tid_reg;
temp_tdest_next = temp_tdest_reg;
temp_tuser_next = temp_tuser_reg;
output_axis_tdata_int = {OUTPUT_DATA_WIDTH{1'b0}};
output_axis_tkeep_int = {OUTPUT_KEEP_WIDTH{1'b0}};
output_axis_tdata_int = {OUTPUT_DATA_WIDTH{1'b0}};
output_axis_tkeep_int = {OUTPUT_KEEP_WIDTH{1'b0}};
output_axis_tvalid_int = 1'b0;
output_axis_tlast_int = 1'b0;
output_axis_tuser_int = 1'b0;
output_axis_tlast_int = 1'b0;
output_axis_tid_int = {ID_WIDTH{1'b0}};
output_axis_tdest_int = {DEST_WIDTH{1'b0}};
output_axis_tuser_int = {USER_WIDTH{1'b0}};
input_axis_tready_next = 1'b0;
@ -151,11 +175,13 @@ always @* begin
input_axis_tready_next = output_axis_tready_int_early;
// transfer through
output_axis_tdata_int = input_axis_tdata;
output_axis_tkeep_int = input_axis_tkeep;
output_axis_tdata_int = input_axis_tdata;
output_axis_tkeep_int = INPUT_KEEP_ENABLE ? input_axis_tkeep : 1'b1;
output_axis_tvalid_int = input_axis_tvalid;
output_axis_tlast_int = input_axis_tlast;
output_axis_tuser_int = input_axis_tuser;
output_axis_tlast_int = input_axis_tlast;
output_axis_tid_int = input_axis_tid;
output_axis_tdest_int = input_axis_tdest;
output_axis_tuser_int = input_axis_tuser;
state_next = STATE_IDLE;
end else if (EXPAND_BUS) begin
@ -166,11 +192,13 @@ always @* begin
if (input_axis_tready & input_axis_tvalid) begin
// word transfer in - store it in data register
// pass complete input word, zero-extended to temp register
temp_tdata_next = input_axis_tdata;
temp_tkeep_next = input_axis_tkeep;
temp_tkeep_next = INPUT_KEEP_ENABLE ? input_axis_tkeep : 1'b1;
temp_tlast_next = input_axis_tlast;
temp_tid_next = input_axis_tid;
temp_tdest_next = input_axis_tdest;
temp_tuser_next = input_axis_tuser;
// first input cycle complete
@ -202,10 +230,10 @@ always @* begin
if (CYCLE_COUNT == 1) begin
// last cycle by counter value
last_cycle = 1'b1;
end else if (input_axis_tkeep[CYCLE_KEEP_WIDTH-1:0] != {CYCLE_KEEP_WIDTH{1'b1}}) begin
end else if (INPUT_KEEP_ENABLE && input_axis_tkeep[CYCLE_KEEP_WIDTH-1:0] != {CYCLE_KEEP_WIDTH{1'b1}}) begin
// last cycle by tkeep fall in current cycle
last_cycle = 1'b1;
end else if (input_axis_tkeep[(CYCLE_KEEP_WIDTH*2)-1:CYCLE_KEEP_WIDTH] == {CYCLE_KEEP_WIDTH{1'b0}}) begin
end else if (INPUT_KEEP_ENABLE && input_axis_tkeep[(CYCLE_KEEP_WIDTH*2)-1:CYCLE_KEEP_WIDTH] == {CYCLE_KEEP_WIDTH{1'b0}}) begin
// last cycle by tkeep fall at end of current cycle
last_cycle = 1'b1;
end else begin
@ -214,16 +242,20 @@ always @* begin
// pass complete input word, zero-extended to temp register
temp_tdata_next = input_axis_tdata;
temp_tkeep_next = input_axis_tkeep;
temp_tkeep_next = INPUT_KEEP_ENABLE ? input_axis_tkeep : 1'b1;
temp_tlast_next = input_axis_tlast;
temp_tid_next = input_axis_tid;
temp_tdest_next = input_axis_tdest;
temp_tuser_next = input_axis_tuser;
// short-circuit and get first word out the door
output_axis_tdata_int = input_axis_tdata[CYCLE_DATA_WIDTH-1:0];
output_axis_tkeep_int = input_axis_tkeep[CYCLE_KEEP_WIDTH-1:0];
output_axis_tdata_int = input_axis_tdata[CYCLE_DATA_WIDTH-1:0];
output_axis_tkeep_int = input_axis_tkeep[CYCLE_KEEP_WIDTH-1:0];
output_axis_tvalid_int = 1'b1;
output_axis_tlast_int = input_axis_tlast & last_cycle;
output_axis_tuser_int = input_axis_tuser & last_cycle;
output_axis_tlast_int = input_axis_tlast & last_cycle;
output_axis_tid_int = input_axis_tid;
output_axis_tdest_int = input_axis_tdest;
output_axis_tuser_int = input_axis_tuser;
if (output_axis_tready_int_reg) begin
// if output register is ready for first word, then move on to the next one
@ -251,14 +283,16 @@ always @* begin
if (input_axis_tready & input_axis_tvalid) begin
// word transfer in - store in data register
temp_tdata_next[cycle_count_reg*CYCLE_DATA_WIDTH +: CYCLE_DATA_WIDTH] = input_axis_tdata;
temp_tkeep_next[cycle_count_reg*CYCLE_KEEP_WIDTH +: CYCLE_KEEP_WIDTH] = input_axis_tkeep;
temp_tkeep_next[cycle_count_reg*CYCLE_KEEP_WIDTH +: CYCLE_KEEP_WIDTH] = INPUT_KEEP_ENABLE ? input_axis_tkeep : 1'b1;
temp_tlast_next = input_axis_tlast;
temp_tid_next = input_axis_tid;
temp_tdest_next = input_axis_tdest;
temp_tuser_next = input_axis_tuser;
cycle_count_next = cycle_count_reg + 1;
if ((cycle_count_reg == CYCLE_COUNT-1) | input_axis_tlast) begin
// terminated by counter or tlast signal, output complete word
// read input word next cycle if output will be ready
@ -278,17 +312,19 @@ always @* begin
if (EXPAND_BUS) begin
// output bus is wider
// do not accept new data
input_axis_tready_next = 1'b0;
// single-cycle output of entire stored word (output wider)
output_axis_tdata_int = temp_tdata_reg;
output_axis_tkeep_int = temp_tkeep_reg;
output_axis_tdata_int = temp_tdata_reg;
output_axis_tkeep_int = temp_tkeep_reg;
output_axis_tvalid_int = 1'b1;
output_axis_tlast_int = temp_tlast_reg;
output_axis_tuser_int = temp_tuser_reg;
output_axis_tlast_int = temp_tlast_reg;
output_axis_tid_int = temp_tid_reg;
output_axis_tdest_int = temp_tdest_reg;
output_axis_tuser_int = temp_tuser_reg;
if (output_axis_tready_int_reg) begin
// word transfer out
@ -297,8 +333,10 @@ always @* begin
// pass complete input word, zero-extended to temp register
temp_tdata_next = input_axis_tdata;
temp_tkeep_next = input_axis_tkeep;
temp_tkeep_next = INPUT_KEEP_ENABLE ? input_axis_tkeep : 1'b1;
temp_tlast_next = input_axis_tlast;
temp_tid_next = input_axis_tid;
temp_tdest_next = input_axis_tdest;
temp_tuser_next = input_axis_tuser;
// first input cycle complete
@ -341,11 +379,13 @@ always @* begin
end
// output current part of stored word (output narrower)
output_axis_tdata_int = temp_tdata_reg[cycle_count_reg*CYCLE_DATA_WIDTH +: CYCLE_DATA_WIDTH];
output_axis_tkeep_int = temp_tkeep_reg[cycle_count_reg*CYCLE_KEEP_WIDTH +: CYCLE_KEEP_WIDTH];
output_axis_tdata_int = temp_tdata_reg[cycle_count_reg*CYCLE_DATA_WIDTH +: CYCLE_DATA_WIDTH];
output_axis_tkeep_int = temp_tkeep_reg[cycle_count_reg*CYCLE_KEEP_WIDTH +: CYCLE_KEEP_WIDTH];
output_axis_tvalid_int = 1'b1;
output_axis_tlast_int = temp_tlast_reg & last_cycle;
output_axis_tuser_int = temp_tuser_reg & last_cycle;
output_axis_tlast_int = temp_tlast_reg & last_cycle;
output_axis_tid_int = temp_tid_reg;
output_axis_tdest_int = temp_tdest_reg;
output_axis_tuser_int = temp_tuser_reg;
if (output_axis_tready_int_reg) begin
// word transfer out
@ -354,7 +394,7 @@ always @* begin
if (last_cycle) begin
// terminated by counter or tlast signal
input_axis_tready_next = 1'b1;
state_next = STATE_IDLE;
end else begin
@ -363,7 +403,7 @@ always @* begin
end
end else begin
state_next = STATE_TRANSFER_OUT;
end
end
end
end
endcase
@ -385,32 +425,40 @@ always @(posedge clk) begin
temp_tdata_reg <= temp_tdata_next;
temp_tkeep_reg <= temp_tkeep_next;
temp_tlast_reg <= temp_tlast_next;
temp_tuser_reg <= temp_tuser_next;
temp_tid_reg <= temp_tid_next;
temp_tdest_reg <= temp_tdest_next;
temp_tuser_reg <= temp_tuser_next;
end
// output datapath logic
reg [OUTPUT_DATA_WIDTH-1:0] output_axis_tdata_reg = {OUTPUT_DATA_WIDTH{1'b0}};
reg [OUTPUT_KEEP_WIDTH-1:0] output_axis_tkeep_reg = {OUTPUT_KEEP_WIDTH{1'b0}};
reg [OUTPUT_DATA_WIDTH-1:0] output_axis_tdata_reg = {OUTPUT_DATA_WIDTH{1'b0}};
reg [OUTPUT_KEEP_WIDTH-1:0] output_axis_tkeep_reg = {OUTPUT_KEEP_WIDTH{1'b0}};
reg output_axis_tvalid_reg = 1'b0, output_axis_tvalid_next;
reg output_axis_tlast_reg = 1'b0;
reg output_axis_tuser_reg = 1'b0;
reg output_axis_tlast_reg = 1'b0;
reg [ID_WIDTH-1:0] output_axis_tid_reg = {ID_WIDTH{1'b0}};
reg [DEST_WIDTH-1:0] output_axis_tdest_reg = {DEST_WIDTH{1'b0}};
reg [USER_WIDTH-1:0] output_axis_tuser_reg = {USER_WIDTH{1'b0}};
reg [OUTPUT_DATA_WIDTH-1:0] temp_axis_tdata_reg = {OUTPUT_DATA_WIDTH{1'b0}};
reg [OUTPUT_KEEP_WIDTH-1:0] temp_axis_tkeep_reg = {OUTPUT_KEEP_WIDTH{1'b0}};
reg [OUTPUT_DATA_WIDTH-1:0] temp_axis_tdata_reg = {OUTPUT_DATA_WIDTH{1'b0}};
reg [OUTPUT_KEEP_WIDTH-1:0] temp_axis_tkeep_reg = {OUTPUT_KEEP_WIDTH{1'b0}};
reg temp_axis_tvalid_reg = 1'b0, temp_axis_tvalid_next;
reg temp_axis_tlast_reg = 1'b0;
reg temp_axis_tuser_reg = 1'b0;
reg temp_axis_tlast_reg = 1'b0;
reg [ID_WIDTH-1:0] temp_axis_tid_reg = {ID_WIDTH{1'b0}};
reg [DEST_WIDTH-1:0] temp_axis_tdest_reg = {DEST_WIDTH{1'b0}};
reg [USER_WIDTH-1:0] temp_axis_tuser_reg = {USER_WIDTH{1'b0}};
// datapath control
reg store_axis_int_to_output;
reg store_axis_int_to_temp;
reg store_axis_temp_to_output;
assign output_axis_tdata = output_axis_tdata_reg;
assign output_axis_tkeep = output_axis_tkeep_reg;
assign output_axis_tdata = output_axis_tdata_reg;
assign output_axis_tkeep = OUTPUT_KEEP_ENABLE ? output_axis_tkeep_reg : {OUTPUT_KEEP_WIDTH{1'b1}};
assign output_axis_tvalid = output_axis_tvalid_reg;
assign output_axis_tlast = output_axis_tlast_reg;
assign output_axis_tuser = output_axis_tuser_reg;
assign output_axis_tlast = output_axis_tlast_reg;
assign output_axis_tid = ID_ENABLE ? output_axis_tid_reg : {ID_WIDTH{1'b0}};
assign output_axis_tdest = DEST_ENABLE ? output_axis_tdest_reg : {DEST_WIDTH{1'b0}};
assign output_axis_tuser = USER_ENABLE ? output_axis_tuser_reg : {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)
assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & (~output_axis_tvalid_reg | ~output_axis_tvalid_int));
@ -423,7 +471,7 @@ always @* begin
store_axis_int_to_output = 1'b0;
store_axis_int_to_temp = 1'b0;
store_axis_temp_to_output = 1'b0;
if (output_axis_tready_int_reg) begin
// input is ready
if (output_axis_tready | ~output_axis_tvalid_reg) begin
@ -459,11 +507,15 @@ always @(posedge clk) begin
output_axis_tdata_reg <= output_axis_tdata_int;
output_axis_tkeep_reg <= output_axis_tkeep_int;
output_axis_tlast_reg <= output_axis_tlast_int;
output_axis_tid_reg <= output_axis_tid_int;
output_axis_tdest_reg <= output_axis_tdest_int;
output_axis_tuser_reg <= output_axis_tuser_int;
end else if (store_axis_temp_to_output) begin
output_axis_tdata_reg <= temp_axis_tdata_reg;
output_axis_tkeep_reg <= temp_axis_tkeep_reg;
output_axis_tlast_reg <= temp_axis_tlast_reg;
output_axis_tid_reg <= temp_axis_tid_reg;
output_axis_tdest_reg <= temp_axis_tdest_reg;
output_axis_tuser_reg <= temp_axis_tuser_reg;
end
@ -471,6 +523,8 @@ always @(posedge clk) begin
temp_axis_tdata_reg <= output_axis_tdata_int;
temp_axis_tkeep_reg <= output_axis_tkeep_int;
temp_axis_tlast_reg <= output_axis_tlast_int;
temp_axis_tid_reg <= output_axis_tid_int;
temp_axis_tdest_reg <= output_axis_tdest_int;
temp_axis_tuser_reg <= output_axis_tuser_int;
end
end

View File

@ -44,9 +44,17 @@ def bench():
# Parameters
INPUT_DATA_WIDTH = 64
INPUT_KEEP_ENABLE = (INPUT_DATA_WIDTH>8)
INPUT_KEEP_WIDTH = (INPUT_DATA_WIDTH/8)
OUTPUT_DATA_WIDTH = 8
OUTPUT_KEEP_ENABLE = (OUTPUT_DATA_WIDTH>8)
OUTPUT_KEEP_WIDTH = (OUTPUT_DATA_WIDTH/8)
ID_ENABLE = 1
ID_WIDTH = 8
DEST_ENABLE = 1
DEST_WIDTH = 8
USER_ENABLE = 1
USER_WIDTH = 1
# Inputs
clk = Signal(bool(0))
@ -54,19 +62,23 @@ def bench():
current_test = Signal(intbv(0)[8:])
input_axis_tdata = Signal(intbv(0)[INPUT_DATA_WIDTH:])
input_axis_tkeep = Signal(intbv(0)[INPUT_KEEP_WIDTH:])
input_axis_tkeep = Signal(intbv(1)[INPUT_KEEP_WIDTH:])
input_axis_tvalid = Signal(bool(0))
input_axis_tlast = Signal(bool(0))
input_axis_tuser = Signal(bool(0))
input_axis_tid = Signal(intbv(0)[ID_WIDTH:])
input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:])
input_axis_tuser = Signal(intbv(0)[USER_WIDTH:])
output_axis_tready = Signal(bool(0))
# Outputs
input_axis_tready = Signal(bool(0))
output_axis_tdata = Signal(intbv(0)[OUTPUT_DATA_WIDTH:])
output_axis_tkeep = Signal(intbv(0)[OUTPUT_KEEP_WIDTH:])
output_axis_tkeep = Signal(intbv(1)[OUTPUT_KEEP_WIDTH:])
output_axis_tvalid = Signal(bool(0))
output_axis_tlast = Signal(bool(0))
output_axis_tuser = Signal(bool(0))
output_axis_tid = Signal(intbv(0)[ID_WIDTH:])
output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:])
output_axis_tuser = Signal(intbv(0)[USER_WIDTH:])
# sources and sinks
source_pause = Signal(bool(0))
@ -82,6 +94,8 @@ def bench():
tvalid=input_axis_tvalid,
tready=input_axis_tready,
tlast=input_axis_tlast,
tid=input_axis_tid,
tdest=input_axis_tdest,
tuser=input_axis_tuser,
pause=source_pause,
name='source'
@ -97,6 +111,8 @@ def bench():
tvalid=output_axis_tvalid,
tready=output_axis_tready,
tlast=output_axis_tlast,
tid=output_axis_tid,
tdest=output_axis_tdest,
tuser=output_axis_tuser,
pause=sink_pause,
name='sink'
@ -117,6 +133,8 @@ def bench():
input_axis_tvalid=input_axis_tvalid,
input_axis_tready=input_axis_tready,
input_axis_tlast=input_axis_tlast,
input_axis_tid=input_axis_tid,
input_axis_tdest=input_axis_tdest,
input_axis_tuser=input_axis_tuser,
output_axis_tdata=output_axis_tdata,
@ -124,6 +142,8 @@ def bench():
output_axis_tvalid=output_axis_tvalid,
output_axis_tready=output_axis_tready,
output_axis_tlast=output_axis_tlast,
output_axis_tid=output_axis_tid,
output_axis_tdest=output_axis_tdest,
output_axis_tuser=output_axis_tuser
)
@ -169,10 +189,14 @@ def bench():
print("test 1: test packet, length %d" % payload_len)
current_test.next = 1
test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
bytearray(range(payload_len)))
test_frame = axis_ep.AXIStreamFrame(
b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
bytearray(range(payload_len)),
id=1,
dest=1,
)
for wait in wait_normal, wait_pause_source, wait_pause_sink:
source.send(test_frame)
@ -197,14 +221,22 @@ def bench():
print("test 2: back-to-back packets, length %d" % payload_len)
current_test.next = 2
test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
bytearray(range(payload_len)))
test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
bytearray(range(payload_len)))
test_frame1 = axis_ep.AXIStreamFrame(
b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
bytearray(range(payload_len)),
id=2,
dest=1,
)
test_frame2 = axis_ep.AXIStreamFrame(
b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
bytearray(range(payload_len)),
id=2,
dest=2,
)
for wait in wait_normal, wait_pause_source, wait_pause_sink:
source.send(test_frame1)
@ -234,16 +266,23 @@ def bench():
print("test 3: tuser assert, length %d" % payload_len)
current_test.next = 3
test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
bytearray(range(payload_len)))
test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
bytearray(range(payload_len)))
test_frame1.user = 1
test_frame1 = axis_ep.AXIStreamFrame(
b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
bytearray(range(payload_len)),
id=3,
dest=1,
last_cycle_user=1
)
test_frame2 = axis_ep.AXIStreamFrame(
b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
bytearray(range(payload_len)),
id=3,
dest=2,
)
for wait in wait_normal, wait_pause_source, wait_pause_sink:
source.send(test_frame1)
@ -260,7 +299,7 @@ def bench():
rx_frame = sink.recv()
assert rx_frame == test_frame1
assert rx_frame.user[-1]
assert rx_frame.last_cycle_user
rx_frame = sink.recv()

View File

@ -32,10 +32,18 @@ THE SOFTWARE.
module test_axis_adapter_64_8;
// Parameters
localparam INPUT_DATA_WIDTH = 64;
localparam INPUT_KEEP_WIDTH = (INPUT_DATA_WIDTH/8);
localparam OUTPUT_DATA_WIDTH = 8;
localparam OUTPUT_KEEP_WIDTH = (OUTPUT_DATA_WIDTH/8);
parameter INPUT_DATA_WIDTH = 64;
parameter INPUT_KEEP_ENABLE = (INPUT_DATA_WIDTH>8);
parameter INPUT_KEEP_WIDTH = (INPUT_DATA_WIDTH/8);
parameter OUTPUT_DATA_WIDTH = 8;
parameter OUTPUT_KEEP_ENABLE = (OUTPUT_DATA_WIDTH>8);
parameter OUTPUT_KEEP_WIDTH = (OUTPUT_DATA_WIDTH/8);
parameter ID_ENABLE = 1;
parameter ID_WIDTH = 8;
parameter DEST_ENABLE = 1;
parameter DEST_WIDTH = 8;
parameter USER_ENABLE = 1;
parameter USER_WIDTH = 1;
// Inputs
reg clk = 0;
@ -46,7 +54,9 @@ reg [INPUT_DATA_WIDTH-1:0] input_axis_tdata = 0;
reg [INPUT_KEEP_WIDTH-1:0] input_axis_tkeep = 0;
reg input_axis_tvalid = 0;
reg input_axis_tlast = 0;
reg input_axis_tuser = 0;
reg [ID_WIDTH-1:0] input_axis_tid = 0;
reg [DEST_WIDTH-1:0] input_axis_tdest = 0;
reg [USER_WIDTH-1:0] input_axis_tuser = 0;
reg output_axis_tready = 0;
// Outputs
@ -55,7 +65,9 @@ wire [OUTPUT_DATA_WIDTH-1:0] output_axis_tdata;
wire [OUTPUT_KEEP_WIDTH-1:0] output_axis_tkeep;
wire output_axis_tvalid;
wire output_axis_tlast;
wire output_axis_tuser;
wire [ID_WIDTH-1:0] output_axis_tid;
wire [DEST_WIDTH-1:0] output_axis_tdest;
wire [USER_WIDTH-1:0] output_axis_tuser;
initial begin
// myhdl integration
@ -67,6 +79,8 @@ initial begin
input_axis_tkeep,
input_axis_tvalid,
input_axis_tlast,
input_axis_tid,
input_axis_tdest,
input_axis_tuser,
output_axis_tready
);
@ -76,6 +90,8 @@ initial begin
output_axis_tkeep,
output_axis_tvalid,
output_axis_tlast,
output_axis_tid,
output_axis_tdest,
output_axis_tuser
);
@ -86,9 +102,17 @@ end
axis_adapter #(
.INPUT_DATA_WIDTH(INPUT_DATA_WIDTH),
.INPUT_KEEP_ENABLE(INPUT_KEEP_ENABLE),
.INPUT_KEEP_WIDTH(INPUT_KEEP_WIDTH),
.OUTPUT_DATA_WIDTH(OUTPUT_DATA_WIDTH),
.OUTPUT_KEEP_WIDTH(OUTPUT_KEEP_WIDTH)
.OUTPUT_KEEP_ENABLE(OUTPUT_KEEP_ENABLE),
.OUTPUT_KEEP_WIDTH(OUTPUT_KEEP_WIDTH),
.ID_ENABLE(ID_ENABLE),
.ID_WIDTH(ID_WIDTH),
.DEST_ENABLE(DEST_ENABLE),
.DEST_WIDTH(DEST_WIDTH),
.USER_ENABLE(USER_ENABLE),
.USER_WIDTH(USER_WIDTH)
)
UUT (
.clk(clk),
@ -99,6 +123,8 @@ UUT (
.input_axis_tvalid(input_axis_tvalid),
.input_axis_tready(input_axis_tready),
.input_axis_tlast(input_axis_tlast),
.input_axis_tid(input_axis_tid),
.input_axis_tdest(input_axis_tdest),
.input_axis_tuser(input_axis_tuser),
// AXI output
.output_axis_tdata(output_axis_tdata),
@ -106,6 +132,8 @@ UUT (
.output_axis_tvalid(output_axis_tvalid),
.output_axis_tready(output_axis_tready),
.output_axis_tlast(output_axis_tlast),
.output_axis_tid(output_axis_tid),
.output_axis_tdest(output_axis_tdest),
.output_axis_tuser(output_axis_tuser)
);

View File

@ -44,9 +44,17 @@ def bench():
# Parameters
INPUT_DATA_WIDTH = 8
INPUT_KEEP_ENABLE = (INPUT_DATA_WIDTH>8)
INPUT_KEEP_WIDTH = (INPUT_DATA_WIDTH/8)
OUTPUT_DATA_WIDTH = 64
OUTPUT_KEEP_ENABLE = (OUTPUT_DATA_WIDTH>8)
OUTPUT_KEEP_WIDTH = (OUTPUT_DATA_WIDTH/8)
ID_ENABLE = 1
ID_WIDTH = 8
DEST_ENABLE = 1
DEST_WIDTH = 8
USER_ENABLE = 1
USER_WIDTH = 1
# Inputs
clk = Signal(bool(0))
@ -54,19 +62,23 @@ def bench():
current_test = Signal(intbv(0)[8:])
input_axis_tdata = Signal(intbv(0)[INPUT_DATA_WIDTH:])
input_axis_tkeep = Signal(intbv(0)[INPUT_KEEP_WIDTH:])
input_axis_tkeep = Signal(intbv(1)[INPUT_KEEP_WIDTH:])
input_axis_tvalid = Signal(bool(0))
input_axis_tlast = Signal(bool(0))
input_axis_tuser = Signal(bool(0))
input_axis_tid = Signal(intbv(0)[ID_WIDTH:])
input_axis_tdest = Signal(intbv(0)[DEST_WIDTH:])
input_axis_tuser = Signal(intbv(0)[USER_WIDTH:])
output_axis_tready = Signal(bool(0))
# Outputs
input_axis_tready = Signal(bool(0))
output_axis_tdata = Signal(intbv(0)[OUTPUT_DATA_WIDTH:])
output_axis_tkeep = Signal(intbv(0)[OUTPUT_KEEP_WIDTH:])
output_axis_tkeep = Signal(intbv(1)[OUTPUT_KEEP_WIDTH:])
output_axis_tvalid = Signal(bool(0))
output_axis_tlast = Signal(bool(0))
output_axis_tuser = Signal(bool(0))
output_axis_tid = Signal(intbv(0)[ID_WIDTH:])
output_axis_tdest = Signal(intbv(0)[DEST_WIDTH:])
output_axis_tuser = Signal(intbv(0)[USER_WIDTH:])
# sources and sinks
source_pause = Signal(bool(0))
@ -82,6 +94,8 @@ def bench():
tvalid=input_axis_tvalid,
tready=input_axis_tready,
tlast=input_axis_tlast,
tid=input_axis_tid,
tdest=input_axis_tdest,
tuser=input_axis_tuser,
pause=source_pause,
name='source'
@ -97,6 +111,8 @@ def bench():
tvalid=output_axis_tvalid,
tready=output_axis_tready,
tlast=output_axis_tlast,
tid=output_axis_tid,
tdest=output_axis_tdest,
tuser=output_axis_tuser,
pause=sink_pause,
name='sink'
@ -117,6 +133,8 @@ def bench():
input_axis_tvalid=input_axis_tvalid,
input_axis_tready=input_axis_tready,
input_axis_tlast=input_axis_tlast,
input_axis_tid=input_axis_tid,
input_axis_tdest=input_axis_tdest,
input_axis_tuser=input_axis_tuser,
output_axis_tdata=output_axis_tdata,
@ -124,6 +142,8 @@ def bench():
output_axis_tvalid=output_axis_tvalid,
output_axis_tready=output_axis_tready,
output_axis_tlast=output_axis_tlast,
output_axis_tid=output_axis_tid,
output_axis_tdest=output_axis_tdest,
output_axis_tuser=output_axis_tuser
)
@ -169,10 +189,14 @@ def bench():
print("test 1: test packet, length %d" % payload_len)
current_test.next = 1
test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
bytearray(range(payload_len)))
test_frame = axis_ep.AXIStreamFrame(
b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
bytearray(range(payload_len)),
id=1,
dest=1,
)
for wait in wait_normal, wait_pause_source, wait_pause_sink:
source.send(test_frame)
@ -197,14 +221,22 @@ def bench():
print("test 2: back-to-back packets, length %d" % payload_len)
current_test.next = 2
test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
bytearray(range(payload_len)))
test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
bytearray(range(payload_len)))
test_frame1 = axis_ep.AXIStreamFrame(
b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
bytearray(range(payload_len)),
id=2,
dest=1,
)
test_frame2 = axis_ep.AXIStreamFrame(
b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
bytearray(range(payload_len)),
id=2,
dest=2,
)
for wait in wait_normal, wait_pause_source, wait_pause_sink:
source.send(test_frame1)
@ -234,16 +266,23 @@ def bench():
print("test 3: tuser assert, length %d" % payload_len)
current_test.next = 3
test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
bytearray(range(payload_len)))
test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
bytearray(range(payload_len)))
test_frame1.user = 1
test_frame1 = axis_ep.AXIStreamFrame(
b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
bytearray(range(payload_len)),
id=3,
dest=1,
last_cycle_user=1
)
test_frame2 = axis_ep.AXIStreamFrame(
b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
bytearray(range(payload_len)),
id=3,
dest=2,
)
for wait in wait_normal, wait_pause_source, wait_pause_sink:
source.send(test_frame1)
@ -260,7 +299,7 @@ def bench():
rx_frame = sink.recv()
assert rx_frame == test_frame1
assert rx_frame.user[-1]
assert rx_frame.last_cycle_user
rx_frame = sink.recv()

View File

@ -32,10 +32,18 @@ THE SOFTWARE.
module test_axis_adapter_8_64;
// Parameters
localparam INPUT_DATA_WIDTH = 8;
localparam INPUT_KEEP_WIDTH = (INPUT_DATA_WIDTH/8);
localparam OUTPUT_DATA_WIDTH = 64;
localparam OUTPUT_KEEP_WIDTH = (OUTPUT_DATA_WIDTH/8);
parameter INPUT_DATA_WIDTH = 8;
parameter INPUT_KEEP_ENABLE = (INPUT_DATA_WIDTH>8);
parameter INPUT_KEEP_WIDTH = (INPUT_DATA_WIDTH/8);
parameter OUTPUT_DATA_WIDTH = 64;
parameter OUTPUT_KEEP_ENABLE = (OUTPUT_DATA_WIDTH>8);
parameter OUTPUT_KEEP_WIDTH = (OUTPUT_DATA_WIDTH/8);
parameter ID_ENABLE = 1;
parameter ID_WIDTH = 8;
parameter DEST_ENABLE = 1;
parameter DEST_WIDTH = 8;
parameter USER_ENABLE = 1;
parameter USER_WIDTH = 1;
// Inputs
reg clk = 0;
@ -46,7 +54,9 @@ reg [INPUT_DATA_WIDTH-1:0] input_axis_tdata = 0;
reg [INPUT_KEEP_WIDTH-1:0] input_axis_tkeep = 0;
reg input_axis_tvalid = 0;
reg input_axis_tlast = 0;
reg input_axis_tuser = 0;
reg [ID_WIDTH-1:0] input_axis_tid = 0;
reg [DEST_WIDTH-1:0] input_axis_tdest = 0;
reg [USER_WIDTH-1:0] input_axis_tuser = 0;
reg output_axis_tready = 0;
// Outputs
@ -55,7 +65,9 @@ wire [OUTPUT_DATA_WIDTH-1:0] output_axis_tdata;
wire [OUTPUT_KEEP_WIDTH-1:0] output_axis_tkeep;
wire output_axis_tvalid;
wire output_axis_tlast;
wire output_axis_tuser;
wire [ID_WIDTH-1:0] output_axis_tid;
wire [DEST_WIDTH-1:0] output_axis_tdest;
wire [USER_WIDTH-1:0] output_axis_tuser;
initial begin
// myhdl integration
@ -67,6 +79,8 @@ initial begin
input_axis_tkeep,
input_axis_tvalid,
input_axis_tlast,
input_axis_tid,
input_axis_tdest,
input_axis_tuser,
output_axis_tready
);
@ -76,6 +90,8 @@ initial begin
output_axis_tkeep,
output_axis_tvalid,
output_axis_tlast,
output_axis_tid,
output_axis_tdest,
output_axis_tuser
);
@ -86,9 +102,17 @@ end
axis_adapter #(
.INPUT_DATA_WIDTH(INPUT_DATA_WIDTH),
.INPUT_KEEP_ENABLE(INPUT_KEEP_ENABLE),
.INPUT_KEEP_WIDTH(INPUT_KEEP_WIDTH),
.OUTPUT_DATA_WIDTH(OUTPUT_DATA_WIDTH),
.OUTPUT_KEEP_WIDTH(OUTPUT_KEEP_WIDTH)
.OUTPUT_KEEP_ENABLE(OUTPUT_KEEP_ENABLE),
.OUTPUT_KEEP_WIDTH(OUTPUT_KEEP_WIDTH),
.ID_ENABLE(ID_ENABLE),
.ID_WIDTH(ID_WIDTH),
.DEST_ENABLE(DEST_ENABLE),
.DEST_WIDTH(DEST_WIDTH),
.USER_ENABLE(USER_ENABLE),
.USER_WIDTH(USER_WIDTH)
)
UUT (
.clk(clk),
@ -99,6 +123,8 @@ UUT (
.input_axis_tvalid(input_axis_tvalid),
.input_axis_tready(input_axis_tready),
.input_axis_tlast(input_axis_tlast),
.input_axis_tid(input_axis_tid),
.input_axis_tdest(input_axis_tdest),
.input_axis_tuser(input_axis_tuser),
// AXI output
.output_axis_tdata(output_axis_tdata),
@ -106,6 +132,8 @@ UUT (
.output_axis_tvalid(output_axis_tvalid),
.output_axis_tready(output_axis_tready),
.output_axis_tlast(output_axis_tlast),
.output_axis_tid(output_axis_tid),
.output_axis_tdest(output_axis_tdest),
.output_axis_tuser(output_axis_tuser)
);