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

Remove AXI stream components

This commit is contained in:
Alex Forencich 2014-11-05 16:59:59 -08:00
parent 588c2742e8
commit 96c6fcd144
36 changed files with 0 additions and 8923 deletions

View File

@ -1,432 +0,0 @@
/*
Copyright (c) 2014 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
// Language: Verilog 2001
`timescale 1ns / 1ps
/*
* AXI4-Stream bus width adapter
*/
module axis_adapter #
(
parameter 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)
)
(
input wire clk,
input wire rst,
/*
* AXI input
*/
input wire [INPUT_DATA_WIDTH-1:0] input_axis_tdata,
input wire [INPUT_KEEP_WIDTH-1:0] input_axis_tkeep,
input wire input_axis_tvalid,
output wire input_axis_tready,
input wire input_axis_tlast,
input wire input_axis_tuser,
/*
* AXI output
*/
output wire [OUTPUT_DATA_WIDTH-1:0] output_axis_tdata,
output wire [OUTPUT_KEEP_WIDTH-1:0] output_axis_tkeep,
output wire output_axis_tvalid,
input wire output_axis_tready,
output wire output_axis_tlast,
output wire output_axis_tuser
);
// bus word widths (must be identical)
localparam INPUT_DATA_WORD_WIDTH = INPUT_DATA_WIDTH / INPUT_KEEP_WIDTH;
localparam OUTPUT_DATA_WORD_WIDTH = OUTPUT_DATA_WIDTH / OUTPUT_KEEP_WIDTH;
// output bus is wider
localparam EXPAND_BUS = OUTPUT_KEEP_WIDTH > INPUT_KEEP_WIDTH;
// 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;
// required number of cycles to match widths
localparam CYCLE_COUNT = EXPAND_BUS ? (OUTPUT_KEEP_WIDTH / INPUT_KEEP_WIDTH) : (INPUT_KEEP_WIDTH / OUTPUT_KEEP_WIDTH);
// 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_WIDTH * INPUT_KEEP_WIDTH != INPUT_DATA_WIDTH) begin
$error("Error: input data width not evenly divisble");
$finish;
end
if (OUTPUT_DATA_WORD_WIDTH * OUTPUT_KEEP_WIDTH != OUTPUT_DATA_WIDTH) begin
$error("Error: output data width not evenly divisble");
$finish;
end
if (INPUT_DATA_WORD_WIDTH != OUTPUT_DATA_WORD_WIDTH) begin
$error("Error: word width mismatch");
$finish;
end
end
// state register
localparam [2:0]
STATE_IDLE = 3'd0,
STATE_TRANSFER_IN = 3'd1,
STATE_TRANSFER_OUT = 3'd2;
reg [2:0] state_reg = STATE_IDLE, state_next;
reg [7:0] cycle_count_reg = 0, cycle_count_next;
reg [DATA_WIDTH-1:0] temp_tdata_reg = 0, temp_tdata_next;
reg [KEEP_WIDTH-1:0] temp_tkeep_reg = 0, temp_tkeep_next;
reg temp_tlast_reg = 0, temp_tlast_next;
reg temp_tuser_reg = 0, 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 = 0;
reg output_axis_tlast_int;
reg output_axis_tuser_int;
wire output_axis_tready_int_early;
reg input_axis_tready_reg = 0, input_axis_tready_next;
assign input_axis_tready = input_axis_tready_reg;
always @* begin
state_next = 3'bz;
cycle_count_next = cycle_count_reg;
temp_tdata_next = temp_tdata_reg;
temp_tkeep_next = temp_tkeep_reg;
temp_tlast_next = temp_tlast_reg;
temp_tuser_next = temp_tuser_reg;
output_axis_tdata_int = 0;
output_axis_tkeep_int = 0;
output_axis_tvalid_int = 0;
output_axis_tlast_int = 0;
output_axis_tuser_int = 0;
input_axis_tready_next = 0;
case (state_reg)
STATE_IDLE: begin
// idle state - no data in registers
if (CYCLE_COUNT == 1) begin
// output and input same width - just act like a register
// accept data next cycle if output register ready next cycle
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_tvalid_int = input_axis_tvalid;
output_axis_tlast_int = input_axis_tlast;
output_axis_tuser_int = input_axis_tuser;
state_next = STATE_IDLE;
end else if (EXPAND_BUS) begin
// output bus is wider
// accept new data
input_axis_tready_next = 1;
if (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_tlast_next = input_axis_tlast;
temp_tuser_next = input_axis_tuser;
// first input cycle complete
cycle_count_next = 1;
if (input_axis_tlast) begin
// got last signal on first cycle, so output it
input_axis_tready_next = 0;
state_next = STATE_TRANSFER_OUT;
end else begin
// otherwise, transfer in the rest of the words
input_axis_tready_next = 1;
state_next = STATE_TRANSFER_IN;
end
end else begin
state_next = STATE_IDLE;
end
end else begin
// output bus is narrower
// accept new data
input_axis_tready_next = 1;
if (input_axis_tvalid) begin
// word transfer in - store it in data register
cycle_count_next = 0;
// pass complete input word, zero-extended to temp register
temp_tdata_next = input_axis_tdata;
temp_tkeep_next = input_axis_tkeep;
temp_tlast_next = input_axis_tlast;
temp_tuser_next = input_axis_tuser;
// short-circuit and get first word out the door
output_axis_tdata_int = input_axis_tdata;
output_axis_tkeep_int = input_axis_tkeep;
output_axis_tvalid_int = 1;
output_axis_tlast_int = input_axis_tlast & ((CYCLE_COUNT == 1) | (input_axis_tkeep[CYCLE_KEEP_WIDTH-1:0] != {CYCLE_KEEP_WIDTH{1'b1}}));
output_axis_tuser_int = input_axis_tuser & ((CYCLE_COUNT == 1) | (input_axis_tkeep[CYCLE_KEEP_WIDTH-1:0] != {CYCLE_KEEP_WIDTH{1'b1}}));
if (output_axis_tready_int) begin
// if output register is ready for first word, then move on to the next one
cycle_count_next = 1;
end
// continue outputting words
input_axis_tready_next = 0;
state_next = STATE_TRANSFER_OUT;
end else begin
state_next = STATE_IDLE;
end
end
end
STATE_TRANSFER_IN: begin
// transfer word to temp registers
// only used when output is wider
// accept new data
input_axis_tready_next = 1;
if (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_tlast_next = input_axis_tlast;
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
input_axis_tready_next = output_axis_tready_int_early;
state_next = STATE_TRANSFER_OUT;
end else begin
// more words to read
input_axis_tready_next = 1;
state_next = STATE_TRANSFER_IN;
end
end else begin
state_next = STATE_TRANSFER_IN;
end
end
STATE_TRANSFER_OUT: begin
// transfer word to output registers
if (EXPAND_BUS) begin
// output bus is wider
// do not accept new data
input_axis_tready_next = 0;
// 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_tvalid_int = 1;
output_axis_tlast_int = temp_tlast_reg;
output_axis_tuser_int = temp_tuser_reg;
if (output_axis_tready_int) begin
// word transfer out
if (input_axis_tready & input_axis_tvalid) begin
// word transfer in
// pass complete input word, zero-extended to temp register
temp_tdata_next = input_axis_tdata;
temp_tkeep_next = input_axis_tkeep;
temp_tlast_next = input_axis_tlast;
temp_tuser_next = input_axis_tuser;
// first input cycle complete
cycle_count_next = 1;
if (input_axis_tlast) begin
// got last signal on first cycle, so output it
input_axis_tready_next = 0;
state_next = STATE_TRANSFER_OUT;
end else begin
// otherwise, transfer in the rest of the words
input_axis_tready_next = 1;
state_next = STATE_TRANSFER_IN;
end
end else begin
input_axis_tready_next = 1;
state_next = STATE_IDLE;
end
end else begin
state_next = STATE_TRANSFER_OUT;
end
end else begin
// output bus is narrower
// do not accept new data
input_axis_tready_next = 0;
// 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_tvalid_int = 1;
output_axis_tlast_int = temp_tlast_reg & ((cycle_count_reg == CYCLE_COUNT-1) | (temp_tkeep_reg[cycle_count_reg*CYCLE_KEEP_WIDTH +: CYCLE_KEEP_WIDTH] != {CYCLE_KEEP_WIDTH{1'b1}}));
output_axis_tuser_int = temp_tuser_reg & ((cycle_count_reg == CYCLE_COUNT-1) | (temp_tkeep_reg[cycle_count_reg*CYCLE_KEEP_WIDTH +: CYCLE_KEEP_WIDTH] != {CYCLE_KEEP_WIDTH{1'b1}}));
if (output_axis_tready_int) begin
// word transfer out
cycle_count_next = cycle_count_reg + 1;
if ((cycle_count_reg == CYCLE_COUNT-1) | (temp_tkeep_reg[cycle_count_reg*CYCLE_KEEP_WIDTH +: CYCLE_KEEP_WIDTH] != {CYCLE_KEEP_WIDTH{1'b1}})) begin
// terminated by counter or tlast signal
input_axis_tready_next = 1;
state_next = STATE_IDLE;
end else begin
// more words to write
state_next = STATE_TRANSFER_OUT;
end
end else begin
state_next = STATE_TRANSFER_OUT;
end
end
end
endcase
end
always @(posedge clk or posedge rst) begin
if (rst) begin
state_reg <= STATE_IDLE;
cycle_count_reg <= 0;
temp_tdata_reg <= 0;
temp_tkeep_reg <= 0;
temp_tlast_reg <= 0;
temp_tuser_reg <= 0;
input_axis_tready_reg <= 0;
end else begin
state_reg <= state_next;
input_axis_tready_reg <= input_axis_tready_next;
temp_tdata_reg <= temp_tdata_next;
temp_tkeep_reg <= temp_tkeep_next;
temp_tlast_reg <= temp_tlast_next;
temp_tuser_reg <= temp_tuser_next;
cycle_count_reg <= cycle_count_next;
end
end
// output datapath logic
reg [OUTPUT_DATA_WIDTH-1:0] output_axis_tdata_reg = 0;
reg [OUTPUT_KEEP_WIDTH-1:0] output_axis_tkeep_reg = 0;
reg output_axis_tvalid_reg = 0;
reg output_axis_tlast_reg = 0;
reg output_axis_tuser_reg = 0;
reg [OUTPUT_DATA_WIDTH-1:0] temp_axis_tdata_reg = 0;
reg [OUTPUT_KEEP_WIDTH-1:0] temp_axis_tkeep_reg = 0;
reg temp_axis_tvalid_reg = 0;
reg temp_axis_tlast_reg = 0;
reg temp_axis_tuser_reg = 0;
assign output_axis_tdata = output_axis_tdata_reg;
assign output_axis_tkeep = output_axis_tkeep_reg;
assign output_axis_tvalid = output_axis_tvalid_reg;
assign output_axis_tlast = output_axis_tlast_reg;
assign output_axis_tuser = output_axis_tuser_reg;
// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle
assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int);
always @(posedge clk or posedge rst) begin
if (rst) begin
output_axis_tdata_reg <= 0;
output_axis_tkeep_reg <= 0;
output_axis_tvalid_reg <= 0;
output_axis_tlast_reg <= 0;
output_axis_tuser_reg <= 0;
output_axis_tready_int <= 0;
temp_axis_tdata_reg <= 0;
temp_axis_tkeep_reg <= 0;
temp_axis_tvalid_reg <= 0;
temp_axis_tlast_reg <= 0;
temp_axis_tuser_reg <= 0;
end else begin
// transfer sink ready state to source
output_axis_tready_int <= output_axis_tready_int_early;
if (output_axis_tready_int) begin
// input is ready
if (output_axis_tready | ~output_axis_tvalid_reg) begin
// output is ready or currently not valid, transfer data to output
output_axis_tdata_reg <= output_axis_tdata_int;
output_axis_tkeep_reg <= output_axis_tkeep_int;
output_axis_tvalid_reg <= output_axis_tvalid_int;
output_axis_tlast_reg <= output_axis_tlast_int;
output_axis_tuser_reg <= output_axis_tuser_int;
end else begin
// output is not ready and currently valid, store input in temp
temp_axis_tdata_reg <= output_axis_tdata_int;
temp_axis_tkeep_reg <= output_axis_tkeep_int;
temp_axis_tvalid_reg <= output_axis_tvalid_int;
temp_axis_tlast_reg <= output_axis_tlast_int;
temp_axis_tuser_reg <= output_axis_tuser_int;
end
end else if (output_axis_tready) begin
// input is not ready, but output is ready
output_axis_tdata_reg <= temp_axis_tdata_reg;
output_axis_tkeep_reg <= temp_axis_tkeep_reg;
output_axis_tvalid_reg <= temp_axis_tvalid_reg;
output_axis_tlast_reg <= temp_axis_tlast_reg;
output_axis_tuser_reg <= temp_axis_tuser_reg;
temp_axis_tdata_reg <= 0;
temp_axis_tkeep_reg <= 0;
temp_axis_tvalid_reg <= 0;
temp_axis_tlast_reg <= 0;
temp_axis_tuser_reg <= 0;
end
end
end
endmodule

View File

@ -1,128 +0,0 @@
/*
Copyright (c) 2013 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
// Language: Verilog 2001
`timescale 1ns / 1ps
/*
* AXI4-Stream FIFO
*/
module axis_fifo #
(
parameter ADDR_WIDTH = 12,
parameter DATA_WIDTH = 8
)
(
input wire clk,
input wire rst,
/*
* AXI input
*/
input wire [DATA_WIDTH-1:0] input_axis_tdata,
input wire input_axis_tvalid,
output wire input_axis_tready,
input wire input_axis_tlast,
input wire input_axis_tuser,
/*
* AXI output
*/
output wire [DATA_WIDTH-1:0] output_axis_tdata,
output wire output_axis_tvalid,
input wire output_axis_tready,
output wire output_axis_tlast,
output wire output_axis_tuser
);
reg [ADDR_WIDTH-1:0] wr_ptr = {ADDR_WIDTH{1'b0}};
reg [ADDR_WIDTH-1:0] rd_ptr = {ADDR_WIDTH{1'b0}};
reg [ADDR_WIDTH-1:0] counter = {ADDR_WIDTH{1'b0}};
reg [DATA_WIDTH+2-1:0] data_out_reg = {1'b0, 1'b0, {DATA_WIDTH{1'b0}}};
//(* RAM_STYLE="BLOCK" *)
reg [DATA_WIDTH+2-1:0] mem[(2**ADDR_WIDTH)-1:0];
reg output_read = 1'b0;
reg output_axis_tvalid_reg = 1'b0;
wire [DATA_WIDTH+2-1:0] data_in = {input_axis_tlast, input_axis_tuser, input_axis_tdata};
wire full = (counter == (2**ADDR_WIDTH)-1);
wire empty = (counter == 0);
wire write = input_axis_tvalid & ~full;
wire read = (output_axis_tready | ~output_axis_tvalid_reg) & ~empty;
assign {output_axis_tlast, output_axis_tuser, output_axis_tdata} = data_out_reg;
assign input_axis_tready = ~full;
assign output_axis_tvalid = output_axis_tvalid_reg;
// write
always @(posedge clk or posedge rst) begin
if (rst) begin
wr_ptr <= 0;
end else if (write) begin
mem[wr_ptr] <= data_in;
wr_ptr <= wr_ptr + 1;
end
end
// read
always @(posedge clk or posedge rst) begin
if (rst) begin
rd_ptr <= 0;
end else if (read) begin
data_out_reg <= mem[rd_ptr];
rd_ptr <= rd_ptr + 1;
end
end
// counter
always @(posedge clk or posedge rst) begin
if (rst) begin
counter <= 0;
end else if (~read & write) begin
counter <= counter + 1;
end else if (read & ~write) begin
counter <= counter - 1;
end
end
// source ready output
always @(posedge clk or posedge rst) begin
if (rst) begin
output_axis_tvalid_reg <= 1'b0;
end else if (output_axis_tready | ~output_axis_tvalid_reg) begin
output_axis_tvalid_reg <= ~empty;
end else begin
output_axis_tvalid_reg <= output_axis_tvalid_reg;
end
end
endmodule

View File

@ -1,131 +0,0 @@
/*
Copyright (c) 2013 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
// Language: Verilog 2001
`timescale 1ns / 1ps
/*
* AXI4-Stream FIFO (64 bit datapath)
*/
module axis_fifo_64 #
(
parameter ADDR_WIDTH = 12,
parameter DATA_WIDTH = 64,
parameter KEEP_WIDTH = (DATA_WIDTH/8)
)
(
input wire clk,
input wire rst,
/*
* AXI input
*/
input wire [DATA_WIDTH-1:0] input_axis_tdata,
input wire [KEEP_WIDTH-1:0] input_axis_tkeep,
input wire input_axis_tvalid,
output wire input_axis_tready,
input wire input_axis_tlast,
input wire input_axis_tuser,
/*
* AXI output
*/
output wire [DATA_WIDTH-1:0] output_axis_tdata,
output wire [KEEP_WIDTH-1:0] output_axis_tkeep,
output wire output_axis_tvalid,
input wire output_axis_tready,
output wire output_axis_tlast,
output wire output_axis_tuser
);
reg [ADDR_WIDTH-1:0] wr_ptr = {ADDR_WIDTH{1'b0}};
reg [ADDR_WIDTH-1:0] rd_ptr = {ADDR_WIDTH{1'b0}};
reg [ADDR_WIDTH-1:0] counter = {ADDR_WIDTH{1'b0}};
reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] data_out_reg = {1'b0, 1'b0, {KEEP_WIDTH{1'b0}}, {DATA_WIDTH{1'b0}}};
//(* RAM_STYLE="BLOCK" *)
reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] mem[(2**ADDR_WIDTH)-1:0];
reg output_read = 1'b0;
reg output_axis_tvalid_reg = 1'b0;
wire [DATA_WIDTH+KEEP_WIDTH+2-1:0] data_in = {input_axis_tlast, input_axis_tuser, input_axis_tkeep, input_axis_tdata};
wire full = (counter == (2**ADDR_WIDTH)-1);
wire empty = (counter == 0);
wire write = input_axis_tvalid & ~full;
wire read = (output_axis_tready | ~output_axis_tvalid_reg) & ~empty;
assign {output_axis_tlast, output_axis_tuser, output_axis_tkeep, output_axis_tdata} = data_out_reg;
assign input_axis_tready = ~full;
assign output_axis_tvalid = output_axis_tvalid_reg;
// write
always @(posedge clk or posedge rst) begin
if (rst) begin
wr_ptr <= 0;
end else if (write) begin
mem[wr_ptr] <= data_in;
wr_ptr <= wr_ptr + 1;
end
end
// read
always @(posedge clk or posedge rst) begin
if (rst) begin
rd_ptr <= 0;
end else if (read) begin
data_out_reg <= mem[rd_ptr];
rd_ptr <= rd_ptr + 1;
end
end
// counter
always @(posedge clk or posedge rst) begin
if (rst) begin
counter <= 0;
end else if (~read & write) begin
counter <= counter + 1;
end else if (read & ~write) begin
counter <= counter - 1;
end
end
// source ready output
always @(posedge clk or posedge rst) begin
if (rst) begin
output_axis_tvalid_reg <= 1'b0;
end else if (output_axis_tready | ~output_axis_tvalid_reg) begin
output_axis_tvalid_reg <= ~empty;
end else begin
output_axis_tvalid_reg <= output_axis_tvalid_reg;
end
end
endmodule

View File

@ -1,417 +0,0 @@
#!/usr/bin/env python
"""axis_frame_join
Generates an AXI Stream frame join module with a specific number of input ports
Usage: axis_frame_join [OPTION]...
-?, --help display this help and exit
-p, --ports specify number of ports
-n, --name specify module name
-o, --output specify output file name
"""
import io
import sys
import getopt
from math import *
from jinja2 import Template
class Usage(Exception):
def __init__(self, msg):
self.msg = msg
def main(argv=None):
if argv is None:
argv = sys.argv
try:
try:
opts, args = getopt.getopt(argv[1:], "?n:p:o:", ["help", "name=", "ports=", "output="])
except getopt.error as msg:
raise Usage(msg)
# more code, unchanged
except Usage as err:
print(err.msg, file=sys.stderr)
print("for help use --help", file=sys.stderr)
return 2
ports = 4
name = None
out_name = None
# process options
for o, a in opts:
if o in ('-?', '--help'):
print(__doc__)
sys.exit(0)
if o in ('-p', '--ports'):
ports = int(a)
if o in ('-n', '--name'):
name = a
if o in ('-o', '--outputs'):
out_name = a
if name is None:
name = "axis_frame_join_{0}".format(ports)
if out_name is None:
out_name = name + ".v"
print("Opening file '%s'..." % out_name)
try:
out_file = open(out_name, 'w')
except Exception as ex:
print("Error opening \"%s\": %s" %(out_name, ex.strerror), file=sys.stderr)
exit(1)
print("Generating {0} port AXI Stream frame joiner {1}...".format(ports, name))
select_width = ceil(log2(ports))
t = Template(u"""/*
Copyright (c) 2014 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
// Language: Verilog 2001
`timescale 1ns / 1ps
/*
* AXI4-Stream {{n}} port frame joiner
*/
module {{name}} #
(
parameter ENABLE_TAG = 1
)
(
input wire clk,
input wire rst,
/*
* AXI inputs
*/
{%- for p in ports %}
input wire [7:0] input_{{p}}_axis_tdata,
input wire input_{{p}}_axis_tvalid,
output wire input_{{p}}_axis_tready,
input wire input_{{p}}_axis_tlast,
input wire input_{{p}}_axis_tuser,
{% endfor %}
/*
* AXI output
*/
output wire [7:0] output_axis_tdata,
output wire output_axis_tvalid,
input wire output_axis_tready,
output wire output_axis_tlast,
output wire output_axis_tuser,
/*
* Configuration
*/
input wire [15:0] tag,
/*
* Status signals
*/
output wire busy
);
// state register
localparam [1:0]
STATE_IDLE = 2'd0,
STATE_WRITE_TAG = 2'd1,
STATE_TRANSFER = 2'd2;
reg [1:0] state_reg = STATE_IDLE, state_next;
reg [2:0] frame_ptr_reg = 0, frame_ptr_next;
reg [{{w-1}}:0] port_sel_reg = 0, port_sel_next;
reg busy_reg = 0, busy_next;
reg [7:0] input_tdata;
reg input_tvalid;
reg input_tlast;
reg input_tuser;
reg output_tuser_reg = 0, output_tuser_next;
{% for p in ports %}
reg input_{{p}}_axis_tready_reg = 0, input_{{p}}_axis_tready_next;
{%- endfor %}
// internal datapath
reg [7:0] output_axis_tdata_int;
reg output_axis_tvalid_int;
reg output_axis_tready_int = 0;
reg output_axis_tlast_int;
reg output_axis_tuser_int;
wire output_axis_tready_int_early;
{% for p in ports %}
assign input_{{p}}_axis_tready = input_{{p}}_axis_tready_reg;
{%- endfor %}
assign busy = busy_reg;
always @* begin
// input port mux
case (port_sel_reg)
{%- for p in ports %}
{{w}}'d{{p}}: begin
input_tdata = input_{{p}}_axis_tdata;
input_tvalid = input_{{p}}_axis_tvalid;
input_tlast = input_{{p}}_axis_tlast;
input_tuser = input_{{p}}_axis_tuser;
end
{%- endfor %}
endcase
end
always @* begin
state_next = 2'bz;
frame_ptr_next = frame_ptr_reg;
port_sel_next = port_sel_reg;
{% for p in ports %}
input_{{p}}_axis_tready_next = 0;
{%- endfor %}
output_axis_tdata_int = 0;
output_axis_tvalid_int = 0;
output_axis_tlast_int = 0;
output_axis_tuser_int = 0;
output_tuser_next = output_tuser_reg;
case (state_reg)
STATE_IDLE: begin
// idle state - wait for data
frame_ptr_next = 0;
port_sel_next = 0;
output_tuser_next = 0;
if (ENABLE_TAG) begin
// next cycle if started will send tag, so do not enable input
input_0_axis_tready_next = 0;
end else begin
// next cycle if started will send data, so enable input
input_0_axis_tready_next = output_axis_tready_int_early;
end
if (input_0_axis_tvalid) begin
// input 0 valid; start transferring data
if (ENABLE_TAG) begin
// tag enabled, so transmit it
if (output_axis_tready_int) begin
// output is ready, so short-circuit first tag byte
frame_ptr_next = 1;
output_axis_tdata_int = tag[15:8];
output_axis_tvalid_int = 1;
end
state_next = STATE_WRITE_TAG;
end else begin
// tag disabled, so transmit data
if (output_axis_tready_int) begin
// output is ready, so short-circuit first data byte
output_axis_tdata_int = input_0_axis_tdata;
output_axis_tvalid_int = 1;
end
state_next = STATE_TRANSFER;
end
end else begin
state_next = STATE_IDLE;
end
end
STATE_WRITE_TAG: begin
// write tag data
if (output_axis_tready_int) begin
// output ready, so send tag byte
state_next = STATE_WRITE_TAG;
frame_ptr_next = frame_ptr_reg + 1;
output_axis_tvalid_int = 1;
case (frame_ptr_reg)
2'd0: output_axis_tdata_int = tag[15:8];
2'd1: begin
// last tag byte - get ready to send data, enable input if ready
output_axis_tdata_int = tag[7:0];
input_0_axis_tready_next = output_axis_tready_int_early;
state_next = STATE_TRANSFER;
end
endcase
end else begin
state_next = STATE_WRITE_TAG;
end
end
STATE_TRANSFER: begin
// transfer input data
// set ready for current input
case (port_sel_reg)
{%- for p in ports %}
{{w}}'d{{p}}: input_{{p}}_axis_tready_next = output_axis_tready_int_early;
{%- endfor %}
endcase
if (input_tvalid & output_axis_tready_int) begin
// output ready, transfer byte
state_next = STATE_TRANSFER;
output_axis_tdata_int = input_tdata;
output_axis_tvalid_int = input_tvalid;
if (input_tlast) begin
// last flag received, switch to next port
port_sel_next = port_sel_reg + 1;
// save tuser - assert tuser out if ANY tuser asserts received
output_tuser_next = output_tuser_next | input_tuser;
// disable input
{%- for p in ports %}
input_{{p}}_axis_tready_next = 0;
{%- endfor %}
if (port_sel_reg == {{n-1}}) begin
// last port - send tlast and tuser and revert to idle
output_axis_tlast_int = 1;
output_axis_tuser_int = output_tuser_next;
state_next = STATE_IDLE;
end else begin
// otherwise, disable enable next port
case (port_sel_next)
{%- for p in ports %}
{{w}}'d{{p}}: input_{{p}}_axis_tready_next = output_axis_tready_int_early;
{%- endfor %}
endcase
end
end
end else begin
state_next = STATE_TRANSFER;
end
end
endcase
end
always @(posedge clk or posedge rst) begin
if (rst) begin
state_reg <= STATE_IDLE;
frame_ptr_reg <= 0;
port_sel_reg <= 0;
{%- for p in ports %}
input_{{p}}_axis_tready_reg <= 0;
{%- endfor %}
output_tuser_reg <= 0;
busy_reg <= 0;
end else begin
state_reg <= state_next;
frame_ptr_reg <= frame_ptr_next;
port_sel_reg <= port_sel_next;
{% for p in ports %}
input_{{p}}_axis_tready_reg <= input_{{p}}_axis_tready_next;
{%- endfor %}
output_tuser_reg <= output_tuser_next;
busy_reg <= state_next != STATE_IDLE;
end
end
// output datapath logic
reg [7:0] output_axis_tdata_reg = 0;
reg output_axis_tvalid_reg = 0;
reg output_axis_tlast_reg = 0;
reg output_axis_tuser_reg = 0;
reg [7:0] temp_axis_tdata_reg = 0;
reg temp_axis_tvalid_reg = 0;
reg temp_axis_tlast_reg = 0;
reg temp_axis_tuser_reg = 0;
assign output_axis_tdata = output_axis_tdata_reg;
assign output_axis_tvalid = output_axis_tvalid_reg;
assign output_axis_tlast = output_axis_tlast_reg;
assign output_axis_tuser = output_axis_tuser_reg;
// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle
assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int);
always @(posedge clk or posedge rst) begin
if (rst) begin
output_axis_tdata_reg <= 0;
output_axis_tvalid_reg <= 0;
output_axis_tlast_reg <= 0;
output_axis_tuser_reg <= 0;
output_axis_tready_int <= 0;
temp_axis_tdata_reg <= 0;
temp_axis_tvalid_reg <= 0;
temp_axis_tlast_reg <= 0;
temp_axis_tuser_reg <= 0;
end else begin
// transfer sink ready state to source
output_axis_tready_int <= output_axis_tready_int_early;
if (output_axis_tready_int) begin
// input is ready
if (output_axis_tready | ~output_axis_tvalid_reg) begin
// output is ready or currently not valid, transfer data to output
output_axis_tdata_reg <= output_axis_tdata_int;
output_axis_tvalid_reg <= output_axis_tvalid_int;
output_axis_tlast_reg <= output_axis_tlast_int;
output_axis_tuser_reg <= output_axis_tuser_int;
end else begin
// output is not ready, store input in temp
temp_axis_tdata_reg <= output_axis_tdata_int;
temp_axis_tvalid_reg <= output_axis_tvalid_int;
temp_axis_tlast_reg <= output_axis_tlast_int;
temp_axis_tuser_reg <= output_axis_tuser_int;
end
end else if (output_axis_tready) begin
// input is not ready, but output is ready
output_axis_tdata_reg <= temp_axis_tdata_reg;
output_axis_tvalid_reg <= temp_axis_tvalid_reg;
output_axis_tlast_reg <= temp_axis_tlast_reg;
output_axis_tuser_reg <= temp_axis_tuser_reg;
temp_axis_tdata_reg <= 0;
temp_axis_tvalid_reg <= 0;
temp_axis_tlast_reg <= 0;
temp_axis_tuser_reg <= 0;
end
end
end
endmodule
""")
out_file.write(t.render(
n=ports,
w=select_width,
name=name,
ports=range(ports)
))
print("Done")
if __name__ == "__main__":
sys.exit(main())

View File

@ -1,377 +0,0 @@
/*
Copyright (c) 2014 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
// Language: Verilog 2001
`timescale 1ns / 1ps
/*
* AXI4-Stream 4 port frame joiner
*/
module axis_frame_join_4 #
(
parameter ENABLE_TAG = 1
)
(
input wire clk,
input wire rst,
/*
* AXI inputs
*/
input wire [7:0] input_0_axis_tdata,
input wire input_0_axis_tvalid,
output wire input_0_axis_tready,
input wire input_0_axis_tlast,
input wire input_0_axis_tuser,
input wire [7:0] input_1_axis_tdata,
input wire input_1_axis_tvalid,
output wire input_1_axis_tready,
input wire input_1_axis_tlast,
input wire input_1_axis_tuser,
input wire [7:0] input_2_axis_tdata,
input wire input_2_axis_tvalid,
output wire input_2_axis_tready,
input wire input_2_axis_tlast,
input wire input_2_axis_tuser,
input wire [7:0] input_3_axis_tdata,
input wire input_3_axis_tvalid,
output wire input_3_axis_tready,
input wire input_3_axis_tlast,
input wire input_3_axis_tuser,
/*
* AXI output
*/
output wire [7:0] output_axis_tdata,
output wire output_axis_tvalid,
input wire output_axis_tready,
output wire output_axis_tlast,
output wire output_axis_tuser,
/*
* Configuration
*/
input wire [15:0] tag,
/*
* Status signals
*/
output wire busy
);
// state register
localparam [1:0]
STATE_IDLE = 2'd0,
STATE_WRITE_TAG = 2'd1,
STATE_TRANSFER = 2'd2;
reg [1:0] state_reg = STATE_IDLE, state_next;
reg [2:0] frame_ptr_reg = 0, frame_ptr_next;
reg [1:0] port_sel_reg = 0, port_sel_next;
reg busy_reg = 0, busy_next;
reg [7:0] input_tdata;
reg input_tvalid;
reg input_tlast;
reg input_tuser;
reg output_tuser_reg = 0, output_tuser_next;
reg input_0_axis_tready_reg = 0, input_0_axis_tready_next;
reg input_1_axis_tready_reg = 0, input_1_axis_tready_next;
reg input_2_axis_tready_reg = 0, input_2_axis_tready_next;
reg input_3_axis_tready_reg = 0, input_3_axis_tready_next;
// internal datapath
reg [7:0] output_axis_tdata_int;
reg output_axis_tvalid_int;
reg output_axis_tready_int = 0;
reg output_axis_tlast_int;
reg output_axis_tuser_int;
wire output_axis_tready_int_early;
assign input_0_axis_tready = input_0_axis_tready_reg;
assign input_1_axis_tready = input_1_axis_tready_reg;
assign input_2_axis_tready = input_2_axis_tready_reg;
assign input_3_axis_tready = input_3_axis_tready_reg;
assign busy = busy_reg;
always @* begin
// input port mux
case (port_sel_reg)
2'd0: begin
input_tdata = input_0_axis_tdata;
input_tvalid = input_0_axis_tvalid;
input_tlast = input_0_axis_tlast;
input_tuser = input_0_axis_tuser;
end
2'd1: begin
input_tdata = input_1_axis_tdata;
input_tvalid = input_1_axis_tvalid;
input_tlast = input_1_axis_tlast;
input_tuser = input_1_axis_tuser;
end
2'd2: begin
input_tdata = input_2_axis_tdata;
input_tvalid = input_2_axis_tvalid;
input_tlast = input_2_axis_tlast;
input_tuser = input_2_axis_tuser;
end
2'd3: begin
input_tdata = input_3_axis_tdata;
input_tvalid = input_3_axis_tvalid;
input_tlast = input_3_axis_tlast;
input_tuser = input_3_axis_tuser;
end
endcase
end
always @* begin
state_next = 2'bz;
frame_ptr_next = frame_ptr_reg;
port_sel_next = port_sel_reg;
input_0_axis_tready_next = 0;
input_1_axis_tready_next = 0;
input_2_axis_tready_next = 0;
input_3_axis_tready_next = 0;
output_axis_tdata_int = 0;
output_axis_tvalid_int = 0;
output_axis_tlast_int = 0;
output_axis_tuser_int = 0;
output_tuser_next = output_tuser_reg;
case (state_reg)
STATE_IDLE: begin
// idle state - wait for data
frame_ptr_next = 0;
port_sel_next = 0;
output_tuser_next = 0;
if (ENABLE_TAG) begin
// next cycle if started will send tag, so do not enable input
input_0_axis_tready_next = 0;
end else begin
// next cycle if started will send data, so enable input
input_0_axis_tready_next = output_axis_tready_int_early;
end
if (input_0_axis_tvalid) begin
// input 0 valid; start transferring data
if (ENABLE_TAG) begin
// tag enabled, so transmit it
if (output_axis_tready_int) begin
// output is ready, so short-circuit first tag byte
frame_ptr_next = 1;
output_axis_tdata_int = tag[15:8];
output_axis_tvalid_int = 1;
end
state_next = STATE_WRITE_TAG;
end else begin
// tag disabled, so transmit data
if (output_axis_tready_int) begin
// output is ready, so short-circuit first data byte
output_axis_tdata_int = input_0_axis_tdata;
output_axis_tvalid_int = 1;
end
state_next = STATE_TRANSFER;
end
end else begin
state_next = STATE_IDLE;
end
end
STATE_WRITE_TAG: begin
// write tag data
if (output_axis_tready_int) begin
// output ready, so send tag byte
state_next = STATE_WRITE_TAG;
frame_ptr_next = frame_ptr_reg + 1;
output_axis_tvalid_int = 1;
case (frame_ptr_reg)
2'd0: output_axis_tdata_int = tag[15:8];
2'd1: begin
// last tag byte - get ready to send data, enable input if ready
output_axis_tdata_int = tag[7:0];
input_0_axis_tready_next = output_axis_tready_int_early;
state_next = STATE_TRANSFER;
end
endcase
end else begin
state_next = STATE_WRITE_TAG;
end
end
STATE_TRANSFER: begin
// transfer input data
// set ready for current input
case (port_sel_reg)
2'd0: input_0_axis_tready_next = output_axis_tready_int_early;
2'd1: input_1_axis_tready_next = output_axis_tready_int_early;
2'd2: input_2_axis_tready_next = output_axis_tready_int_early;
2'd3: input_3_axis_tready_next = output_axis_tready_int_early;
endcase
if (input_tvalid & output_axis_tready_int) begin
// output ready, transfer byte
state_next = STATE_TRANSFER;
output_axis_tdata_int = input_tdata;
output_axis_tvalid_int = input_tvalid;
if (input_tlast) begin
// last flag received, switch to next port
port_sel_next = port_sel_reg + 1;
// save tuser - assert tuser out if ANY tuser asserts received
output_tuser_next = output_tuser_next | input_tuser;
// disable input
input_0_axis_tready_next = 0;
input_1_axis_tready_next = 0;
input_2_axis_tready_next = 0;
input_3_axis_tready_next = 0;
if (port_sel_reg == 3) begin
// last port - send tlast and tuser and revert to idle
output_axis_tlast_int = 1;
output_axis_tuser_int = output_tuser_next;
state_next = STATE_IDLE;
end else begin
// otherwise, disable enable next port
case (port_sel_next)
2'd0: input_0_axis_tready_next = output_axis_tready_int_early;
2'd1: input_1_axis_tready_next = output_axis_tready_int_early;
2'd2: input_2_axis_tready_next = output_axis_tready_int_early;
2'd3: input_3_axis_tready_next = output_axis_tready_int_early;
endcase
end
end
end else begin
state_next = STATE_TRANSFER;
end
end
endcase
end
always @(posedge clk or posedge rst) begin
if (rst) begin
state_reg <= STATE_IDLE;
frame_ptr_reg <= 0;
port_sel_reg <= 0;
input_0_axis_tready_reg <= 0;
input_1_axis_tready_reg <= 0;
input_2_axis_tready_reg <= 0;
input_3_axis_tready_reg <= 0;
output_tuser_reg <= 0;
busy_reg <= 0;
end else begin
state_reg <= state_next;
frame_ptr_reg <= frame_ptr_next;
port_sel_reg <= port_sel_next;
input_0_axis_tready_reg <= input_0_axis_tready_next;
input_1_axis_tready_reg <= input_1_axis_tready_next;
input_2_axis_tready_reg <= input_2_axis_tready_next;
input_3_axis_tready_reg <= input_3_axis_tready_next;
output_tuser_reg <= output_tuser_next;
busy_reg <= state_next != STATE_IDLE;
end
end
// output datapath logic
reg [7:0] output_axis_tdata_reg = 0;
reg output_axis_tvalid_reg = 0;
reg output_axis_tlast_reg = 0;
reg output_axis_tuser_reg = 0;
reg [7:0] temp_axis_tdata_reg = 0;
reg temp_axis_tvalid_reg = 0;
reg temp_axis_tlast_reg = 0;
reg temp_axis_tuser_reg = 0;
assign output_axis_tdata = output_axis_tdata_reg;
assign output_axis_tvalid = output_axis_tvalid_reg;
assign output_axis_tlast = output_axis_tlast_reg;
assign output_axis_tuser = output_axis_tuser_reg;
// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle
assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int);
always @(posedge clk or posedge rst) begin
if (rst) begin
output_axis_tdata_reg <= 0;
output_axis_tvalid_reg <= 0;
output_axis_tlast_reg <= 0;
output_axis_tuser_reg <= 0;
output_axis_tready_int <= 0;
temp_axis_tdata_reg <= 0;
temp_axis_tvalid_reg <= 0;
temp_axis_tlast_reg <= 0;
temp_axis_tuser_reg <= 0;
end else begin
// transfer sink ready state to source
output_axis_tready_int <= output_axis_tready_int_early;
if (output_axis_tready_int) begin
// input is ready
if (output_axis_tready | ~output_axis_tvalid_reg) begin
// output is ready or currently not valid, transfer data to output
output_axis_tdata_reg <= output_axis_tdata_int;
output_axis_tvalid_reg <= output_axis_tvalid_int;
output_axis_tlast_reg <= output_axis_tlast_int;
output_axis_tuser_reg <= output_axis_tuser_int;
end else begin
// output is not ready, store input in temp
temp_axis_tdata_reg <= output_axis_tdata_int;
temp_axis_tvalid_reg <= output_axis_tvalid_int;
temp_axis_tlast_reg <= output_axis_tlast_int;
temp_axis_tuser_reg <= output_axis_tuser_int;
end
end else if (output_axis_tready) begin
// input is not ready, but output is ready
output_axis_tdata_reg <= temp_axis_tdata_reg;
output_axis_tvalid_reg <= temp_axis_tvalid_reg;
output_axis_tlast_reg <= temp_axis_tlast_reg;
output_axis_tuser_reg <= temp_axis_tuser_reg;
temp_axis_tdata_reg <= 0;
temp_axis_tvalid_reg <= 0;
temp_axis_tlast_reg <= 0;
temp_axis_tuser_reg <= 0;
end
end
end
endmodule

View File

@ -1,79 +0,0 @@
/*
Copyright (c) 2014 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
// Language: Verilog 2001
`timescale 1ns / 1ps
/*
* AXI4-Stream to LocalLink bridge
*/
module axis_ll_bridge #
(
parameter DATA_WIDTH = 8
)
(
input wire clk,
input wire rst,
/*
* AXI input
*/
input wire [DATA_WIDTH-1:0] axis_tdata,
input wire axis_tvalid,
output wire axis_tready,
input wire axis_tlast,
/*
* LocalLink output
*/
output wire [DATA_WIDTH-1:0] ll_data_out,
output wire ll_sof_out_n,
output wire ll_eof_out_n,
output wire ll_src_rdy_out_n,
input wire ll_dst_rdy_in_n
);
reg last_tlast = 1'b1;
always @(posedge clk or posedge rst) begin
if (rst) begin
last_tlast = 1'b1;
end else begin
if (axis_tvalid & axis_tready) last_tlast = axis_tlast;
end
end
// high for packet length 1 -> cannot set SOF and EOF in same cycle
// invalid packets are discarded
wire invalid = axis_tvalid & axis_tlast & last_tlast;
assign axis_tready = ~ll_dst_rdy_in_n;
assign ll_data_out = axis_tdata;
assign ll_sof_out_n = ~(last_tlast & axis_tvalid & ~invalid);
assign ll_eof_out_n = ~(axis_tlast & ~invalid);
assign ll_src_rdy_out_n = ~(axis_tvalid & ~invalid);
endmodule

View File

@ -1,188 +0,0 @@
/*
Copyright (c) 2014 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
// Language: Verilog 2001
`timescale 1ns / 1ps
/*
* AXI4-Stream rate limiter
*/
module axis_rate_limit #
(
parameter DATA_WIDTH = 64,
parameter KEEP_WIDTH = (DATA_WIDTH/8)
)
(
input wire clk,
input wire rst,
/*
* AXI input
*/
input wire [DATA_WIDTH-1:0] input_axis_tdata,
input wire input_axis_tvalid,
output wire input_axis_tready,
input wire input_axis_tlast,
input wire input_axis_tuser,
/*
* AXI output
*/
output wire [DATA_WIDTH-1:0] output_axis_tdata,
output wire output_axis_tvalid,
input wire output_axis_tready,
output wire output_axis_tlast,
output wire output_axis_tuser,
/*
* Configuration
*/
input wire [7:0] rate_num,
input wire [7:0] rate_denom,
input wire rate_by_frame
);
// internal datapath
reg [DATA_WIDTH-1:0] output_axis_tdata_int;
reg output_axis_tvalid_int;
reg output_axis_tready_int = 0;
reg output_axis_tlast_int;
reg output_axis_tuser_int;
wire output_axis_tready_int_early;
reg [23:0] acc_reg = 0, acc_next;
reg pause;
reg frame_reg = 0, frame_next;
reg input_axis_tready_reg = 0, input_axis_tready_next;
assign input_axis_tready = input_axis_tready_reg;
always @* begin
acc_next = acc_reg;
pause = 0;
frame_next = frame_reg & ~input_axis_tlast;
if (acc_reg >= rate_num) begin
acc_next = acc_reg - rate_num;
end
if (input_axis_tready & input_axis_tvalid) begin
// read input
frame_next = ~input_axis_tlast;
acc_next = acc_reg + (rate_denom - rate_num);
end
if (acc_next >= rate_num) begin
if (rate_by_frame) begin
pause = ~frame_next;
end else begin
pause = 1;
end
end
input_axis_tready_next = output_axis_tready_int_early & ~pause;
output_axis_tdata_int = input_axis_tdata;
output_axis_tvalid_int = input_axis_tvalid & input_axis_tready;
output_axis_tlast_int = input_axis_tlast;
output_axis_tuser_int = input_axis_tuser;
end
always @(posedge clk or posedge rst) begin
if (rst) begin
acc_reg <= 0;
frame_reg <= 0;
input_axis_tready_reg <= 0;
end else begin
acc_reg <= acc_next;
frame_reg <= frame_next;
input_axis_tready_reg <= input_axis_tready_next;
end
end
// output datapath logic
reg [DATA_WIDTH-1:0] output_axis_tdata_reg = 0;
reg output_axis_tvalid_reg = 0;
reg output_axis_tlast_reg = 0;
reg output_axis_tuser_reg = 0;
reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = 0;
reg temp_axis_tvalid_reg = 0;
reg temp_axis_tlast_reg = 0;
reg temp_axis_tuser_reg = 0;
assign output_axis_tdata = output_axis_tdata_reg;
assign output_axis_tvalid = output_axis_tvalid_reg;
assign output_axis_tlast = output_axis_tlast_reg;
assign output_axis_tuser = output_axis_tuser_reg;
// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle
assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int);
always @(posedge clk or posedge rst) begin
if (rst) begin
output_axis_tdata_reg <= 0;
output_axis_tvalid_reg <= 0;
output_axis_tlast_reg <= 0;
output_axis_tuser_reg <= 0;
output_axis_tready_int <= 0;
temp_axis_tdata_reg <= 0;
temp_axis_tvalid_reg <= 0;
temp_axis_tlast_reg <= 0;
temp_axis_tuser_reg <= 0;
end else begin
// transfer sink ready state to source
output_axis_tready_int <= output_axis_tready_int_early;
if (output_axis_tready_int) begin
// input is ready
if (output_axis_tready | ~output_axis_tvalid_reg) begin
// output is ready or currently not valid, transfer data to output
output_axis_tdata_reg <= output_axis_tdata_int;
output_axis_tvalid_reg <= output_axis_tvalid_int;
output_axis_tlast_reg <= output_axis_tlast_int;
output_axis_tuser_reg <= output_axis_tuser_int;
end else begin
// output is not ready, store input in temp
temp_axis_tdata_reg <= output_axis_tdata_int;
temp_axis_tvalid_reg <= output_axis_tvalid_int;
temp_axis_tlast_reg <= output_axis_tlast_int;
temp_axis_tuser_reg <= output_axis_tuser_int;
end
end else if (output_axis_tready) begin
// input is not ready, but output is ready
output_axis_tdata_reg <= temp_axis_tdata_reg;
output_axis_tvalid_reg <= temp_axis_tvalid_reg;
output_axis_tlast_reg <= temp_axis_tlast_reg;
output_axis_tuser_reg <= temp_axis_tuser_reg;
temp_axis_tdata_reg <= 0;
temp_axis_tvalid_reg <= 0;
temp_axis_tlast_reg <= 0;
temp_axis_tuser_reg <= 0;
end
end
end
endmodule

View File

@ -1,201 +0,0 @@
/*
Copyright (c) 2014 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
// Language: Verilog 2001
`timescale 1ns / 1ps
/*
* AXI4-Stream rate limiter (64 bit datapath)
*/
module axis_rate_limit_64 #
(
parameter DATA_WIDTH = 64,
parameter KEEP_WIDTH = (DATA_WIDTH/8)
)
(
input wire clk,
input wire rst,
/*
* AXI input
*/
input wire [DATA_WIDTH-1:0] input_axis_tdata,
input wire [KEEP_WIDTH-1:0] input_axis_tkeep,
input wire input_axis_tvalid,
output wire input_axis_tready,
input wire input_axis_tlast,
input wire input_axis_tuser,
/*
* AXI output
*/
output wire [DATA_WIDTH-1:0] output_axis_tdata,
output wire [KEEP_WIDTH-1:0] output_axis_tkeep,
output wire output_axis_tvalid,
input wire output_axis_tready,
output wire output_axis_tlast,
output wire output_axis_tuser,
/*
* Configuration
*/
input wire [7:0] rate_num,
input wire [7:0] rate_denom,
input wire rate_by_frame
);
// internal datapath
reg [DATA_WIDTH-1:0] output_axis_tdata_int;
reg [KEEP_WIDTH-1:0] output_axis_tkeep_int;
reg output_axis_tvalid_int;
reg output_axis_tready_int = 0;
reg output_axis_tlast_int;
reg output_axis_tuser_int;
wire output_axis_tready_int_early;
reg [23:0] acc_reg = 0, acc_next;
reg pause;
reg frame_reg = 0, frame_next;
reg input_axis_tready_reg = 0, input_axis_tready_next;
assign input_axis_tready = input_axis_tready_reg;
always @* begin
acc_next = acc_reg;
pause = 0;
frame_next = frame_reg & ~input_axis_tlast;
if (acc_reg >= rate_num) begin
acc_next = acc_reg - rate_num;
end
if (input_axis_tready & input_axis_tvalid) begin
// read input
frame_next = ~input_axis_tlast;
acc_next = acc_reg + (rate_denom - rate_num);
end
if (acc_next >= rate_num) begin
if (rate_by_frame) begin
pause = ~frame_next;
end else begin
pause = 1;
end
end
input_axis_tready_next = output_axis_tready_int_early & ~pause;
output_axis_tdata_int = input_axis_tdata;
output_axis_tkeep_int = input_axis_tkeep;
output_axis_tvalid_int = input_axis_tvalid & input_axis_tready;
output_axis_tlast_int = input_axis_tlast;
output_axis_tuser_int = input_axis_tuser;
end
always @(posedge clk or posedge rst) begin
if (rst) begin
acc_reg <= 0;
frame_reg <= 0;
input_axis_tready_reg <= 0;
end else begin
acc_reg <= acc_next;
frame_reg <= frame_next;
input_axis_tready_reg <= input_axis_tready_next;
end
end
// output datapath logic
reg [DATA_WIDTH-1:0] output_axis_tdata_reg = 0;
reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = 0;
reg output_axis_tvalid_reg = 0;
reg output_axis_tlast_reg = 0;
reg output_axis_tuser_reg = 0;
reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = 0;
reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = 0;
reg temp_axis_tvalid_reg = 0;
reg temp_axis_tlast_reg = 0;
reg temp_axis_tuser_reg = 0;
assign output_axis_tdata = output_axis_tdata_reg;
assign output_axis_tkeep = output_axis_tkeep_reg;
assign output_axis_tvalid = output_axis_tvalid_reg;
assign output_axis_tlast = output_axis_tlast_reg;
assign output_axis_tuser = output_axis_tuser_reg;
// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle
assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int);
always @(posedge clk or posedge rst) begin
if (rst) begin
output_axis_tdata_reg <= 0;
output_axis_tkeep_reg <= 0;
output_axis_tvalid_reg <= 0;
output_axis_tlast_reg <= 0;
output_axis_tuser_reg <= 0;
output_axis_tready_int <= 0;
temp_axis_tdata_reg <= 0;
temp_axis_tkeep_reg <= 0;
temp_axis_tvalid_reg <= 0;
temp_axis_tlast_reg <= 0;
temp_axis_tuser_reg <= 0;
end else begin
// transfer sink ready state to source
output_axis_tready_int <= output_axis_tready_int_early;
if (output_axis_tready_int) begin
// input is ready
if (output_axis_tready | ~output_axis_tvalid_reg) begin
// output is ready or currently not valid, transfer data to output
output_axis_tdata_reg <= output_axis_tdata_int;
output_axis_tkeep_reg <= output_axis_tkeep_int;
output_axis_tvalid_reg <= output_axis_tvalid_int;
output_axis_tlast_reg <= output_axis_tlast_int;
output_axis_tuser_reg <= output_axis_tuser_int;
end else begin
// output is not ready, store input in temp
temp_axis_tdata_reg <= output_axis_tdata_int;
temp_axis_tkeep_reg <= output_axis_tkeep_int;
temp_axis_tvalid_reg <= output_axis_tvalid_int;
temp_axis_tlast_reg <= output_axis_tlast_int;
temp_axis_tuser_reg <= output_axis_tuser_int;
end
end else if (output_axis_tready) begin
// input is not ready, but output is ready
output_axis_tdata_reg <= temp_axis_tdata_reg;
output_axis_tkeep_reg <= temp_axis_tkeep_reg;
output_axis_tvalid_reg <= temp_axis_tvalid_reg;
output_axis_tlast_reg <= temp_axis_tlast_reg;
output_axis_tuser_reg <= temp_axis_tuser_reg;
temp_axis_tdata_reg <= 0;
temp_axis_tkeep_reg <= 0;
temp_axis_tvalid_reg <= 0;
temp_axis_tlast_reg <= 0;
temp_axis_tuser_reg <= 0;
end
end
end
endmodule

View File

@ -1,124 +0,0 @@
/*
Copyright (c) 2014 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
// Language: Verilog 2001
`timescale 1ns / 1ps
/*
* AXI4-Stream register
*/
module axis_register #
(
parameter DATA_WIDTH = 8
)
(
input wire clk,
input wire rst,
/*
* AXI input
*/
input wire [DATA_WIDTH-1:0] input_axis_tdata,
input wire input_axis_tvalid,
output wire input_axis_tready,
input wire input_axis_tlast,
input wire input_axis_tuser,
/*
* AXI output
*/
output wire [DATA_WIDTH-1:0] output_axis_tdata,
output wire output_axis_tvalid,
input wire output_axis_tready,
output wire output_axis_tlast,
output wire output_axis_tuser
);
// datapath registers
reg input_axis_tready_reg = 0;
reg [DATA_WIDTH-1:0] output_axis_tdata_reg = 0;
reg output_axis_tvalid_reg = 0;
reg output_axis_tlast_reg = 0;
reg output_axis_tuser_reg = 0;
reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = 0;
reg temp_axis_tvalid_reg = 0;
reg temp_axis_tlast_reg = 0;
reg temp_axis_tuser_reg = 0;
assign input_axis_tready = input_axis_tready_reg;
assign output_axis_tdata = output_axis_tdata_reg;
assign output_axis_tvalid = output_axis_tvalid_reg;
assign output_axis_tlast = output_axis_tlast_reg;
assign output_axis_tuser = output_axis_tuser_reg;
always @(posedge clk or posedge rst) begin
if (rst) begin
input_axis_tready_reg <= 0;
output_axis_tdata_reg <= 0;
output_axis_tvalid_reg <= 0;
output_axis_tlast_reg <= 0;
output_axis_tuser_reg <= 0;
temp_axis_tdata_reg <= 0;
temp_axis_tvalid_reg <= 0;
temp_axis_tlast_reg <= 0;
temp_axis_tuser_reg <= 0;
end else begin
// transfer sink ready state to source
// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle
input_axis_tready_reg <= output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~input_axis_tvalid);
if (input_axis_tready_reg) begin
// input is ready
if (output_axis_tready | ~output_axis_tvalid_reg) begin
// output is ready or currently not valid, transfer data to output
output_axis_tdata_reg <= input_axis_tdata;
output_axis_tvalid_reg <= input_axis_tvalid;
output_axis_tlast_reg <= input_axis_tlast;
output_axis_tuser_reg <= input_axis_tuser;
end else begin
// output is not ready, store input in temp
temp_axis_tdata_reg <= input_axis_tdata;
temp_axis_tvalid_reg <= input_axis_tvalid;
temp_axis_tlast_reg <= input_axis_tlast;
temp_axis_tuser_reg <= input_axis_tuser;
end
end else if (output_axis_tready) begin
// input is not ready, but output is ready
output_axis_tdata_reg <= temp_axis_tdata_reg;
output_axis_tvalid_reg <= temp_axis_tvalid_reg;
output_axis_tlast_reg <= temp_axis_tlast_reg;
output_axis_tuser_reg <= temp_axis_tuser_reg;
temp_axis_tdata_reg <= 0;
temp_axis_tvalid_reg <= 0;
temp_axis_tlast_reg <= 0;
temp_axis_tuser_reg <= 0;
end
end
end
endmodule

View File

@ -1,136 +0,0 @@
/*
Copyright (c) 2014 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
// Language: Verilog 2001
`timescale 1ns / 1ps
/*
* AXI4-Stream register (64 bit datapath)
*/
module axis_register_64 #
(
parameter DATA_WIDTH = 64,
parameter KEEP_WIDTH = (DATA_WIDTH/8)
)
(
input wire clk,
input wire rst,
/*
* AXI input
*/
input wire [DATA_WIDTH-1:0] input_axis_tdata,
input wire [KEEP_WIDTH-1:0] input_axis_tkeep,
input wire input_axis_tvalid,
output wire input_axis_tready,
input wire input_axis_tlast,
input wire input_axis_tuser,
/*
* AXI output
*/
output wire [DATA_WIDTH-1:0] output_axis_tdata,
output wire [KEEP_WIDTH-1:0] output_axis_tkeep,
output wire output_axis_tvalid,
input wire output_axis_tready,
output wire output_axis_tlast,
output wire output_axis_tuser
);
// datapath registers
reg input_axis_tready_reg = 0;
reg [DATA_WIDTH-1:0] output_axis_tdata_reg = 0;
reg [KEEP_WIDTH-1:0] output_axis_tkeep_reg = 0;
reg output_axis_tvalid_reg = 0;
reg output_axis_tlast_reg = 0;
reg output_axis_tuser_reg = 0;
reg [DATA_WIDTH-1:0] temp_axis_tdata_reg = 0;
reg [KEEP_WIDTH-1:0] temp_axis_tkeep_reg = 0;
reg temp_axis_tvalid_reg = 0;
reg temp_axis_tlast_reg = 0;
reg temp_axis_tuser_reg = 0;
assign input_axis_tready = input_axis_tready_reg;
assign output_axis_tdata = output_axis_tdata_reg;
assign output_axis_tkeep = output_axis_tkeep_reg;
assign output_axis_tvalid = output_axis_tvalid_reg;
assign output_axis_tlast = output_axis_tlast_reg;
assign output_axis_tuser = output_axis_tuser_reg;
always @(posedge clk or posedge rst) begin
if (rst) begin
input_axis_tready_reg <= 0;
output_axis_tdata_reg <= 0;
output_axis_tkeep_reg <= 0;
output_axis_tvalid_reg <= 0;
output_axis_tlast_reg <= 0;
output_axis_tuser_reg <= 0;
temp_axis_tdata_reg <= 0;
temp_axis_tkeep_reg <= 0;
temp_axis_tvalid_reg <= 0;
temp_axis_tlast_reg <= 0;
temp_axis_tuser_reg <= 0;
end else begin
// transfer sink ready state to source
// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle
input_axis_tready_reg <= output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~input_axis_tvalid);
if (input_axis_tready_reg) begin
// input is ready
if (output_axis_tready | ~output_axis_tvalid_reg) begin
// output is ready or currently not valid, transfer data to output
output_axis_tdata_reg <= input_axis_tdata;
output_axis_tkeep_reg <= input_axis_tkeep;
output_axis_tvalid_reg <= input_axis_tvalid;
output_axis_tlast_reg <= input_axis_tlast;
output_axis_tuser_reg <= input_axis_tuser;
end else begin
// output is not ready, store input in temp
temp_axis_tdata_reg <= input_axis_tdata;
temp_axis_tkeep_reg <= input_axis_tkeep;
temp_axis_tvalid_reg <= input_axis_tvalid;
temp_axis_tlast_reg <= input_axis_tlast;
temp_axis_tuser_reg <= input_axis_tuser;
end
end else if (output_axis_tready) begin
// input is not ready, but output is ready
output_axis_tdata_reg <= temp_axis_tdata_reg;
output_axis_tkeep_reg <= temp_axis_tkeep_reg;
output_axis_tvalid_reg <= temp_axis_tvalid_reg;
output_axis_tlast_reg <= temp_axis_tlast_reg;
output_axis_tuser_reg <= temp_axis_tuser_reg;
temp_axis_tdata_reg <= 0;
temp_axis_tkeep_reg <= 0;
temp_axis_tvalid_reg <= 0;
temp_axis_tlast_reg <= 0;
temp_axis_tuser_reg <= 0;
end
end
end
endmodule

View File

@ -1,317 +0,0 @@
/*
Copyright (c) 2014 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
// Language: Verilog 2001
`timescale 1ns / 1ps
/*
* AXI4-Stream statistics counter
*/
module axis_stat_counter #
(
parameter DATA_WIDTH = 64,
parameter KEEP_WIDTH = (DATA_WIDTH/8)
)
(
input wire clk,
input wire rst,
/*
* AXI monitor
*/
input wire [KEEP_WIDTH-1:0] monitor_axis_tkeep,
input wire monitor_axis_tvalid,
input wire monitor_axis_tready,
input wire monitor_axis_tlast,
/*
* AXI status data output
*/
output wire [7:0] output_axis_tdata,
output wire output_axis_tvalid,
input wire output_axis_tready,
output wire output_axis_tlast,
output wire output_axis_tuser,
/*
* Configuration
*/
input wire [15:0] tag,
input wire trigger,
/*
* Status
*/
output wire busy
);
// state register
localparam [1:0]
STATE_IDLE = 2'd0,
STATE_OUTPUT_DATA = 2'd1;
reg [1:0] state_reg = STATE_IDLE, state_next;
reg [31:0] tick_count_reg = 0, tick_count_next;
reg [31:0] byte_count_reg = 0, byte_count_next;
reg [31:0] frame_count_reg = 0, frame_count_next;
reg frame_reg = 0, frame_next;
reg store_output;
reg [5:0] frame_ptr_reg = 0, frame_ptr_next;
reg [31:0] tick_count_output_reg = 0;
reg [31:0] byte_count_output_reg = 0;
reg [31:0] frame_count_output_reg = 0;
reg busy_reg = 0;
// internal datapath
reg [7:0] output_axis_tdata_int;
reg output_axis_tvalid_int;
reg output_axis_tready_int = 0;
reg output_axis_tlast_int;
reg output_axis_tuser_int;
wire output_axis_tready_int_early;
assign busy = busy_reg;
function [3:0] keep2count;
input [7:0] k;
case (k)
8'b00000000: keep2count = 0;
8'b00000001: keep2count = 1;
8'b00000011: keep2count = 2;
8'b00000111: keep2count = 3;
8'b00001111: keep2count = 4;
8'b00011111: keep2count = 5;
8'b00111111: keep2count = 6;
8'b01111111: keep2count = 7;
8'b11111111: keep2count = 8;
endcase
endfunction
function [7:0] count2keep;
input [3:0] k;
case (k)
4'd0: count2keep = 8'b00000000;
4'd1: count2keep = 8'b00000001;
4'd2: count2keep = 8'b00000011;
4'd3: count2keep = 8'b00000111;
4'd4: count2keep = 8'b00001111;
4'd5: count2keep = 8'b00011111;
4'd6: count2keep = 8'b00111111;
4'd7: count2keep = 8'b01111111;
4'd8: count2keep = 8'b11111111;
endcase
endfunction
always @* begin
state_next = 2'bz;
tick_count_next = tick_count_reg;
byte_count_next = byte_count_reg;
frame_count_next = frame_count_reg;
frame_next = frame_reg;
output_axis_tdata_int = 0;
output_axis_tvalid_int = 0;
output_axis_tlast_int = 0;
output_axis_tuser_int = 0;
store_output = 0;
frame_ptr_next = frame_ptr_reg;
// data readout
case (state_reg)
STATE_IDLE: begin
if (trigger) begin
store_output = 1;
tick_count_next = 0;
byte_count_next = 0;
frame_count_next = 0;
frame_ptr_next = 0;
if (output_axis_tready_int) begin
frame_ptr_next = 1;
output_axis_tdata_int = tag[15:8];
output_axis_tvalid_int = 1;
end
state_next = STATE_OUTPUT_DATA;
end else begin
state_next = STATE_IDLE;
end
end
STATE_OUTPUT_DATA: begin
if (output_axis_tready_int) begin
state_next = STATE_OUTPUT_DATA;
frame_ptr_next = frame_ptr_reg + 1;
output_axis_tvalid_int = 1;
case (frame_ptr_reg)
5'd00: output_axis_tdata_int = tag[15:8];
5'd01: output_axis_tdata_int = tag[7:0];
5'd02: output_axis_tdata_int = tick_count_output_reg[31:24];
5'd03: output_axis_tdata_int = tick_count_output_reg[23:16];
5'd04: output_axis_tdata_int = tick_count_output_reg[15: 8];
5'd05: output_axis_tdata_int = tick_count_output_reg[ 7: 0];
5'd06: output_axis_tdata_int = byte_count_output_reg[31:24];
5'd07: output_axis_tdata_int = byte_count_output_reg[23:16];
5'd08: output_axis_tdata_int = byte_count_output_reg[15: 8];
5'd09: output_axis_tdata_int = byte_count_output_reg[ 7: 0];
5'd10: output_axis_tdata_int = frame_count_output_reg[31:24];
5'd11: output_axis_tdata_int = frame_count_output_reg[23:16];
5'd12: output_axis_tdata_int = frame_count_output_reg[15: 8];
5'd13: begin
output_axis_tdata_int = frame_count_output_reg[ 7: 0];
output_axis_tlast_int = 1;
state_next = STATE_IDLE;
end
endcase
end else begin
state_next = STATE_OUTPUT_DATA;
end
end
endcase
// stats collection
// increment tick count by number of words that can be transferred per cycle
tick_count_next = tick_count_next + KEEP_WIDTH;
if (monitor_axis_tready & monitor_axis_tvalid) begin
// valid transfer cycle
// increment byte count by number of words transferred
byte_count_next = byte_count_next + keep2count(monitor_axis_tkeep);
// count frames
if (monitor_axis_tlast) begin
// end of frame
frame_next = 0;
end else if (~frame_reg) begin
// first word after end of frame
frame_count_next = frame_count_next + 1;
frame_next = 1;
end
end
end
always @(posedge clk or posedge rst) begin
if (rst) begin
state_reg <= STATE_IDLE;
tick_count_reg <= 0;
byte_count_reg <= 0;
frame_count_reg <= 0;
frame_reg <= 0;
frame_ptr_reg <= 0;
busy_reg <= 0;
tick_count_output_reg <= 0;
byte_count_output_reg <= 0;
frame_count_output_reg <= 0;
end else begin
state_reg <= state_next;
tick_count_reg <= tick_count_next;
byte_count_reg <= byte_count_next;
frame_count_reg <= frame_count_next;
frame_reg <= frame_next;
frame_ptr_reg <= frame_ptr_next;
busy_reg <= state_next != STATE_IDLE;
if (store_output) begin
tick_count_output_reg <= tick_count_reg;
byte_count_output_reg <= byte_count_reg;
frame_count_output_reg <= frame_count_reg;
end
end
end
// output datapath logic
reg [7:0] output_axis_tdata_reg = 0;
reg output_axis_tvalid_reg = 0;
reg output_axis_tlast_reg = 0;
reg output_axis_tuser_reg = 0;
reg [7:0] temp_axis_tdata_reg = 0;
reg temp_axis_tvalid_reg = 0;
reg temp_axis_tlast_reg = 0;
reg temp_axis_tuser_reg = 0;
assign output_axis_tdata = output_axis_tdata_reg;
assign output_axis_tvalid = output_axis_tvalid_reg;
assign output_axis_tlast = output_axis_tlast_reg;
assign output_axis_tuser = output_axis_tuser_reg;
// enable ready input next cycle if output is ready or if there is space in both output registers or if there is space in the temp register that will not be filled next cycle
assign output_axis_tready_int_early = output_axis_tready | (~temp_axis_tvalid_reg & ~output_axis_tvalid_reg) | (~temp_axis_tvalid_reg & ~output_axis_tvalid_int);
always @(posedge clk or posedge rst) begin
if (rst) begin
output_axis_tdata_reg <= 0;
output_axis_tvalid_reg <= 0;
output_axis_tlast_reg <= 0;
output_axis_tuser_reg <= 0;
output_axis_tready_int <= 0;
temp_axis_tdata_reg <= 0;
temp_axis_tvalid_reg <= 0;
temp_axis_tlast_reg <= 0;
temp_axis_tuser_reg <= 0;
end else begin
// transfer sink ready state to source
output_axis_tready_int <= output_axis_tready_int_early;
if (output_axis_tready_int) begin
// input is ready
if (output_axis_tready | ~output_axis_tvalid_reg) begin
// output is ready or currently not valid, transfer data to output
output_axis_tdata_reg <= output_axis_tdata_int;
output_axis_tvalid_reg <= output_axis_tvalid_int;
output_axis_tlast_reg <= output_axis_tlast_int;
output_axis_tuser_reg <= output_axis_tuser_int;
end else begin
// output is not ready, store input in temp
temp_axis_tdata_reg <= output_axis_tdata_int;
temp_axis_tvalid_reg <= output_axis_tvalid_int;
temp_axis_tlast_reg <= output_axis_tlast_int;
temp_axis_tuser_reg <= output_axis_tuser_int;
end
end else if (output_axis_tready) begin
// input is not ready, but output is ready
output_axis_tdata_reg <= temp_axis_tdata_reg;
output_axis_tvalid_reg <= temp_axis_tvalid_reg;
output_axis_tlast_reg <= temp_axis_tlast_reg;
output_axis_tuser_reg <= temp_axis_tuser_reg;
temp_axis_tdata_reg <= 0;
temp_axis_tvalid_reg <= 0;
temp_axis_tlast_reg <= 0;
temp_axis_tuser_reg <= 0;
end
end
end
endmodule

View File

@ -1,64 +0,0 @@
/*
Copyright (c) 2014 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
// Language: Verilog 2001
`timescale 1ns / 1ps
/*
* LocalLink to AXI4-Stream bridge
*/
module ll_axis_bridge #
(
parameter DATA_WIDTH = 8
)
(
input wire clk,
input wire rst,
/*
* LocalLink input
*/
input wire [DATA_WIDTH-1:0] ll_data_in,
input wire ll_sof_in_n,
input wire ll_eof_in_n,
input wire ll_src_rdy_in_n,
output wire ll_dst_rdy_out_n,
/*
* AXI output
*/
output wire [DATA_WIDTH-1:0] axis_tdata,
output wire axis_tvalid,
input wire axis_tready,
output wire axis_tlast
);
assign axis_tdata = ll_data_in;
assign axis_tvalid = ~ll_src_rdy_in_n;
assign axis_tlast = ~ll_eof_in_n;
assign ll_dst_rdy_out_n = ~axis_tready;
endmodule

View File

@ -1,318 +0,0 @@
#!/usr/bin/env python2
"""
Copyright (c) 2014 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""
from myhdl import *
import os
from Queue import Queue
import axis_ep
module = 'axis_adapter'
srcs = []
srcs.append("../rtl/%s.v" % module)
srcs.append("test_%s_64_8.v" % module)
src = ' '.join(srcs)
build_cmd = "iverilog -o test_%s.vvp %s" % (module, src)
def dut_axis_adapter_64_8(clk,
rst,
current_test,
input_axis_tdata,
input_axis_tkeep,
input_axis_tvalid,
input_axis_tready,
input_axis_tlast,
input_axis_tuser,
output_axis_tdata,
output_axis_tkeep,
output_axis_tvalid,
output_axis_tready,
output_axis_tlast,
output_axis_tuser):
if os.system(build_cmd):
raise Exception("Error running build command")
return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module,
clk=clk,
rst=rst,
current_test=current_test,
input_axis_tdata=input_axis_tdata,
input_axis_tkeep=input_axis_tkeep,
input_axis_tvalid=input_axis_tvalid,
input_axis_tready=input_axis_tready,
input_axis_tlast=input_axis_tlast,
input_axis_tuser=input_axis_tuser,
output_axis_tdata=output_axis_tdata,
output_axis_tkeep=output_axis_tkeep,
output_axis_tvalid=output_axis_tvalid,
output_axis_tready=output_axis_tready,
output_axis_tlast=output_axis_tlast,
output_axis_tuser=output_axis_tuser)
def bench():
# Inputs
clk = Signal(bool(0))
rst = Signal(bool(0))
current_test = Signal(intbv(0)[8:])
input_axis_tdata = Signal(intbv(0)[64:])
input_axis_tkeep = Signal(intbv(0)[8:])
input_axis_tvalid = Signal(bool(0))
input_axis_tlast = Signal(bool(0))
input_axis_tuser = Signal(bool(0))
output_axis_tready = Signal(bool(0))
# Outputs
input_axis_tready = Signal(bool(0))
output_axis_tdata = Signal(intbv(0)[8:])
output_axis_tkeep = Signal(intbv(0)[1:])
output_axis_tvalid = Signal(bool(0))
output_axis_tlast = Signal(bool(0))
output_axis_tuser = Signal(bool(0))
# sources and sinks
source_queue = Queue()
source_pause = Signal(bool(0))
sink_queue = Queue()
sink_pause = Signal(bool(0))
source = axis_ep.AXIStreamSource(clk,
rst,
tdata=input_axis_tdata,
tkeep=input_axis_tkeep,
tvalid=input_axis_tvalid,
tready=input_axis_tready,
tlast=input_axis_tlast,
tuser=input_axis_tuser,
fifo=source_queue,
pause=source_pause,
name='source')
sink = axis_ep.AXIStreamSink(clk,
rst,
tdata=output_axis_tdata,
tkeep=output_axis_tkeep,
tvalid=output_axis_tvalid,
tready=output_axis_tready,
tlast=output_axis_tlast,
tuser=output_axis_tuser,
fifo=sink_queue,
pause=sink_pause,
name='sink')
# DUT
dut = dut_axis_adapter_64_8(clk,
rst,
current_test,
input_axis_tdata,
input_axis_tkeep,
input_axis_tvalid,
input_axis_tready,
input_axis_tlast,
input_axis_tuser,
output_axis_tdata,
output_axis_tkeep,
output_axis_tvalid,
output_axis_tready,
output_axis_tlast,
output_axis_tuser)
@always(delay(4))
def clkgen():
clk.next = not clk
def wait_normal():
while input_axis_tvalid or output_axis_tvalid:
yield clk.posedge
def wait_pause_source():
while input_axis_tvalid or output_axis_tvalid:
source_pause.next = True
yield clk.posedge
yield clk.posedge
yield clk.posedge
source_pause.next = False
yield clk.posedge
def wait_pause_sink():
while input_axis_tvalid or output_axis_tvalid:
sink_pause.next = True
yield clk.posedge
yield clk.posedge
yield clk.posedge
sink_pause.next = False
yield clk.posedge
@instance
def check():
yield delay(100)
yield clk.posedge
rst.next = 1
yield clk.posedge
rst.next = 0
yield clk.posedge
yield delay(100)
yield clk.posedge
for payload_len in range(1,18):
yield clk.posedge
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)))
for wait in wait_normal, wait_pause_source, wait_pause_sink:
source_queue.put(test_frame)
yield clk.posedge
yield clk.posedge
yield wait()
yield clk.posedge
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame
assert sink_queue.empty()
yield delay(100)
yield clk.posedge
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)))
for wait in wait_normal, wait_pause_source, wait_pause_sink:
source_queue.put(test_frame1)
source_queue.put(test_frame2)
yield clk.posedge
yield clk.posedge
yield wait()
yield clk.posedge
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame1
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame2
assert sink_queue.empty()
yield delay(100)
yield clk.posedge
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
for wait in wait_normal, wait_pause_source, wait_pause_sink:
source_queue.put(test_frame1)
source_queue.put(test_frame2)
yield clk.posedge
yield clk.posedge
yield wait()
yield clk.posedge
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame1
assert rx_frame.user[-1]
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame2
assert sink_queue.empty()
yield delay(100)
raise StopSimulation
return dut, source, sink, clkgen, check
def test_bench():
os.chdir(os.path.dirname(os.path.abspath(__file__)))
sim = Simulation(bench())
sim.run()
if __name__ == '__main__':
print("Running test...")
test_bench()

View File

@ -1,105 +0,0 @@
/*
Copyright (c) 2014 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
// Language: Verilog 2001
`timescale 1 ns / 1 ps
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);
// Inputs
reg clk = 0;
reg rst = 0;
reg [7:0] current_test = 0;
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 output_axis_tready = 0;
// Outputs
wire input_axis_tready;
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;
initial begin
// myhdl integration
$from_myhdl(clk,
rst,
current_test,
input_axis_tdata,
input_axis_tkeep,
input_axis_tvalid,
input_axis_tlast,
input_axis_tuser,
output_axis_tready);
$to_myhdl(input_axis_tready,
output_axis_tdata,
output_axis_tkeep,
output_axis_tvalid,
output_axis_tlast,
output_axis_tuser);
// dump file
$dumpfile("test_axis_adapter_64_8.lxt");
$dumpvars(0, test_axis_adapter_64_8);
end
axis_adapter #(
.INPUT_DATA_WIDTH(INPUT_DATA_WIDTH),
.INPUT_KEEP_WIDTH(INPUT_KEEP_WIDTH),
.OUTPUT_DATA_WIDTH(OUTPUT_DATA_WIDTH),
.OUTPUT_KEEP_WIDTH(OUTPUT_KEEP_WIDTH)
)
UUT (
.clk(clk),
.rst(rst),
// AXI input
.input_axis_tdata(input_axis_tdata),
.input_axis_tkeep(input_axis_tkeep),
.input_axis_tvalid(input_axis_tvalid),
.input_axis_tready(input_axis_tready),
.input_axis_tlast(input_axis_tlast),
.input_axis_tuser(input_axis_tuser),
// AXI output
.output_axis_tdata(output_axis_tdata),
.output_axis_tkeep(output_axis_tkeep),
.output_axis_tvalid(output_axis_tvalid),
.output_axis_tready(output_axis_tready),
.output_axis_tlast(output_axis_tlast),
.output_axis_tuser(output_axis_tuser)
);
endmodule

View File

@ -1,318 +0,0 @@
#!/usr/bin/env python2
"""
Copyright (c) 2014 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""
from myhdl import *
import os
from Queue import Queue
import axis_ep
module = 'axis_adapter'
srcs = []
srcs.append("../rtl/%s.v" % module)
srcs.append("test_%s_8_64.v" % module)
src = ' '.join(srcs)
build_cmd = "iverilog -o test_%s.vvp %s" % (module, src)
def dut_axis_adapter_8_64(clk,
rst,
current_test,
input_axis_tdata,
input_axis_tkeep,
input_axis_tvalid,
input_axis_tready,
input_axis_tlast,
input_axis_tuser,
output_axis_tdata,
output_axis_tkeep,
output_axis_tvalid,
output_axis_tready,
output_axis_tlast,
output_axis_tuser):
if os.system(build_cmd):
raise Exception("Error running build command")
return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module,
clk=clk,
rst=rst,
current_test=current_test,
input_axis_tdata=input_axis_tdata,
input_axis_tkeep=input_axis_tkeep,
input_axis_tvalid=input_axis_tvalid,
input_axis_tready=input_axis_tready,
input_axis_tlast=input_axis_tlast,
input_axis_tuser=input_axis_tuser,
output_axis_tdata=output_axis_tdata,
output_axis_tkeep=output_axis_tkeep,
output_axis_tvalid=output_axis_tvalid,
output_axis_tready=output_axis_tready,
output_axis_tlast=output_axis_tlast,
output_axis_tuser=output_axis_tuser)
def bench():
# Inputs
clk = Signal(bool(0))
rst = Signal(bool(0))
current_test = Signal(intbv(0)[8:])
input_axis_tdata = Signal(intbv(0)[8:])
input_axis_tkeep = Signal(intbv(0)[1:])
input_axis_tvalid = Signal(bool(0))
input_axis_tlast = Signal(bool(0))
input_axis_tuser = Signal(bool(0))
output_axis_tready = Signal(bool(0))
# Outputs
input_axis_tready = Signal(bool(0))
output_axis_tdata = Signal(intbv(0)[64:])
output_axis_tkeep = Signal(intbv(0)[8:])
output_axis_tvalid = Signal(bool(0))
output_axis_tlast = Signal(bool(0))
output_axis_tuser = Signal(bool(0))
# sources and sinks
source_queue = Queue()
source_pause = Signal(bool(0))
sink_queue = Queue()
sink_pause = Signal(bool(0))
source = axis_ep.AXIStreamSource(clk,
rst,
tdata=input_axis_tdata,
tkeep=input_axis_tkeep,
tvalid=input_axis_tvalid,
tready=input_axis_tready,
tlast=input_axis_tlast,
tuser=input_axis_tuser,
fifo=source_queue,
pause=source_pause,
name='source')
sink = axis_ep.AXIStreamSink(clk,
rst,
tdata=output_axis_tdata,
tkeep=output_axis_tkeep,
tvalid=output_axis_tvalid,
tready=output_axis_tready,
tlast=output_axis_tlast,
tuser=output_axis_tuser,
fifo=sink_queue,
pause=sink_pause,
name='sink')
# DUT
dut = dut_axis_adapter_8_64(clk,
rst,
current_test,
input_axis_tdata,
input_axis_tkeep,
input_axis_tvalid,
input_axis_tready,
input_axis_tlast,
input_axis_tuser,
output_axis_tdata,
output_axis_tkeep,
output_axis_tvalid,
output_axis_tready,
output_axis_tlast,
output_axis_tuser)
@always(delay(4))
def clkgen():
clk.next = not clk
def wait_normal():
while input_axis_tvalid or output_axis_tvalid:
yield clk.posedge
def wait_pause_source():
while input_axis_tvalid or output_axis_tvalid:
source_pause.next = True
yield clk.posedge
yield clk.posedge
yield clk.posedge
source_pause.next = False
yield clk.posedge
def wait_pause_sink():
while input_axis_tvalid or output_axis_tvalid:
sink_pause.next = True
yield clk.posedge
yield clk.posedge
yield clk.posedge
sink_pause.next = False
yield clk.posedge
@instance
def check():
yield delay(100)
yield clk.posedge
rst.next = 1
yield clk.posedge
rst.next = 0
yield clk.posedge
yield delay(100)
yield clk.posedge
for payload_len in range(1,18):
yield clk.posedge
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)))
for wait in wait_normal, wait_pause_source, wait_pause_sink:
source_queue.put(test_frame)
yield clk.posedge
yield clk.posedge
yield wait()
yield clk.posedge
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame
assert sink_queue.empty()
yield delay(100)
yield clk.posedge
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)))
for wait in wait_normal, wait_pause_source, wait_pause_sink:
source_queue.put(test_frame1)
source_queue.put(test_frame2)
yield clk.posedge
yield clk.posedge
yield wait()
yield clk.posedge
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame1
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame2
assert sink_queue.empty()
yield delay(100)
yield clk.posedge
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
for wait in wait_normal, wait_pause_source, wait_pause_sink:
source_queue.put(test_frame1)
source_queue.put(test_frame2)
yield clk.posedge
yield clk.posedge
yield wait()
yield clk.posedge
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame1
assert rx_frame.user[-1]
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame2
assert sink_queue.empty()
yield delay(100)
raise StopSimulation
return dut, source, sink, clkgen, check
def test_bench():
os.chdir(os.path.dirname(os.path.abspath(__file__)))
sim = Simulation(bench())
sim.run()
if __name__ == '__main__':
print("Running test...")
test_bench()

View File

@ -1,105 +0,0 @@
/*
Copyright (c) 2014 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
// Language: Verilog 2001
`timescale 1 ns / 1 ps
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);
// Inputs
reg clk = 0;
reg rst = 0;
reg [7:0] current_test = 0;
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 output_axis_tready = 0;
// Outputs
wire input_axis_tready;
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;
initial begin
// myhdl integration
$from_myhdl(clk,
rst,
current_test,
input_axis_tdata,
input_axis_tkeep,
input_axis_tvalid,
input_axis_tlast,
input_axis_tuser,
output_axis_tready);
$to_myhdl(input_axis_tready,
output_axis_tdata,
output_axis_tkeep,
output_axis_tvalid,
output_axis_tlast,
output_axis_tuser);
// dump file
$dumpfile("test_axis_adapter_8_64.lxt");
$dumpvars(0, test_axis_adapter_8_64);
end
axis_adapter #(
.INPUT_DATA_WIDTH(INPUT_DATA_WIDTH),
.INPUT_KEEP_WIDTH(INPUT_KEEP_WIDTH),
.OUTPUT_DATA_WIDTH(OUTPUT_DATA_WIDTH),
.OUTPUT_KEEP_WIDTH(OUTPUT_KEEP_WIDTH)
)
UUT (
.clk(clk),
.rst(rst),
// AXI input
.input_axis_tdata(input_axis_tdata),
.input_axis_tkeep(input_axis_tkeep),
.input_axis_tvalid(input_axis_tvalid),
.input_axis_tready(input_axis_tready),
.input_axis_tlast(input_axis_tlast),
.input_axis_tuser(input_axis_tuser),
// AXI output
.output_axis_tdata(output_axis_tdata),
.output_axis_tkeep(output_axis_tkeep),
.output_axis_tvalid(output_axis_tvalid),
.output_axis_tready(output_axis_tready),
.output_axis_tlast(output_axis_tlast),
.output_axis_tuser(output_axis_tuser)
);
endmodule

View File

@ -1,396 +0,0 @@
#!/usr/bin/env python2
"""
Copyright (c) 2014 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""
from myhdl import *
import os
from Queue import Queue
import axis_ep
module = 'axis_fifo'
srcs = []
srcs.append("../rtl/%s.v" % module)
srcs.append("test_%s.v" % module)
src = ' '.join(srcs)
build_cmd = "iverilog -o test_%s.vvp %s" % (module, src)
def dut_axis_fifo(clk,
rst,
current_test,
input_axis_tdata,
input_axis_tvalid,
input_axis_tready,
input_axis_tlast,
input_axis_tuser,
output_axis_tdata,
output_axis_tvalid,
output_axis_tready,
output_axis_tlast,
output_axis_tuser):
if os.system(build_cmd):
raise Exception("Error running build command")
return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module,
clk=clk,
rst=rst,
current_test=current_test,
input_axis_tdata=input_axis_tdata,
input_axis_tvalid=input_axis_tvalid,
input_axis_tready=input_axis_tready,
input_axis_tlast=input_axis_tlast,
input_axis_tuser=input_axis_tuser,
output_axis_tdata=output_axis_tdata,
output_axis_tvalid=output_axis_tvalid,
output_axis_tready=output_axis_tready,
output_axis_tlast=output_axis_tlast,
output_axis_tuser=output_axis_tuser)
def bench():
# Inputs
clk = Signal(bool(0))
rst = Signal(bool(0))
current_test = Signal(intbv(0)[8:])
input_axis_tdata = Signal(intbv(0)[8:])
input_axis_tvalid = Signal(bool(0))
input_axis_tlast = Signal(bool(0))
input_axis_tuser = Signal(bool(0))
output_axis_tready = Signal(bool(0))
# Outputs
input_axis_tready = Signal(bool(0))
output_axis_tdata = Signal(intbv(0)[8:])
output_axis_tvalid = Signal(bool(0))
output_axis_tlast = Signal(bool(0))
output_axis_tuser = Signal(bool(0))
# sources and sinks
source_queue = Queue()
source_pause = Signal(bool(0))
sink_queue = Queue()
sink_pause = Signal(bool(0))
source = axis_ep.AXIStreamSource(clk,
rst,
tdata=input_axis_tdata,
tvalid=input_axis_tvalid,
tready=input_axis_tready,
tlast=input_axis_tlast,
tuser=input_axis_tuser,
fifo=source_queue,
pause=source_pause,
name='source')
sink = axis_ep.AXIStreamSink(clk,
rst,
tdata=output_axis_tdata,
tvalid=output_axis_tvalid,
tready=output_axis_tready,
tlast=output_axis_tlast,
tuser=output_axis_tuser,
fifo=sink_queue,
pause=sink_pause,
name='sink')
# DUT
dut = dut_axis_fifo(clk,
rst,
current_test,
input_axis_tdata,
input_axis_tvalid,
input_axis_tready,
input_axis_tlast,
input_axis_tuser,
output_axis_tdata,
output_axis_tvalid,
output_axis_tready,
output_axis_tlast,
output_axis_tuser)
@always(delay(4))
def clkgen():
clk.next = not clk
@instance
def check():
yield delay(100)
yield clk.posedge
rst.next = 1
yield clk.posedge
rst.next = 0
yield clk.posedge
yield delay(100)
yield clk.posedge
yield clk.posedge
yield clk.posedge
print("test 1: test packet")
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' +
b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
source_queue.put(test_frame)
yield clk.posedge
yield output_axis_tlast.posedge
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame
yield delay(100)
yield clk.posedge
print("test 2: longer packet")
current_test.next = 2
test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
bytearray(range(256)))
source_queue.put(test_frame)
yield clk.posedge
yield output_axis_tlast.posedge
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame
yield clk.posedge
print("test 3: test packet with pauses")
current_test.next = 3
test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
source_queue.put(test_frame)
yield clk.posedge
yield delay(64)
yield clk.posedge
source_pause.next = True
yield delay(32)
yield clk.posedge
source_pause.next = False
yield delay(64)
yield clk.posedge
sink_pause.next = True
yield delay(32)
yield clk.posedge
sink_pause.next = False
yield output_axis_tlast.posedge
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame
yield delay(100)
yield clk.posedge
print("test 4: back-to-back packets")
current_test.next = 4
test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
source_queue.put(test_frame1)
source_queue.put(test_frame2)
yield clk.posedge
yield output_axis_tlast.posedge
yield clk.posedge
yield output_axis_tlast.posedge
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame1
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame2
yield delay(100)
yield clk.posedge
print("test 5: alternate pause source")
current_test.next = 5
test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
source_queue.put(test_frame1)
source_queue.put(test_frame2)
yield clk.posedge
while input_axis_tvalid or output_axis_tvalid:
source_pause.next = True
yield clk.posedge
yield clk.posedge
yield clk.posedge
source_pause.next = False
yield clk.posedge
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame1
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame2
yield delay(100)
yield clk.posedge
print("test 6: alternate pause sink")
current_test.next = 6
test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
source_queue.put(test_frame1)
source_queue.put(test_frame2)
yield clk.posedge
while input_axis_tvalid or output_axis_tvalid:
sink_pause.next = True
yield clk.posedge
yield clk.posedge
yield clk.posedge
sink_pause.next = False
yield clk.posedge
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame1
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame2
yield delay(100)
yield clk.posedge
print("test 7: tuser assert")
current_test.next = 7
test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
test_frame.user = 1
source_queue.put(test_frame)
yield clk.posedge
yield output_axis_tlast.posedge
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame
assert rx_frame.user[-1]
yield delay(100)
raise StopSimulation
return dut, source, sink, clkgen, check
def test_bench():
os.chdir(os.path.dirname(os.path.abspath(__file__)))
sim = Simulation(bench())
sim.run()
if __name__ == '__main__':
print("Running test...")
test_bench()

View File

@ -1,91 +0,0 @@
/*
Copyright (c) 2014 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
// Language: Verilog 2001
`timescale 1 ns / 1 ps
module test_axis_fifo;
// Inputs
reg clk = 0;
reg rst = 0;
reg [7:0] current_test = 0;
reg [7:0] input_axis_tdata = 0;
reg input_axis_tvalid = 0;
reg input_axis_tlast = 0;
reg input_axis_tuser = 0;
reg output_axis_tready = 0;
// Outputs
wire input_axis_tready;
wire [7:0] output_axis_tdata;
wire output_axis_tvalid;
wire output_axis_tlast;
wire output_axis_tuser;
initial begin
// myhdl integration
$from_myhdl(clk,
rst,
current_test,
input_axis_tdata,
input_axis_tvalid,
input_axis_tlast,
input_axis_tuser,
output_axis_tready);
$to_myhdl(input_axis_tready,
output_axis_tdata,
output_axis_tvalid,
output_axis_tlast,
output_axis_tuser);
// dump file
$dumpfile("test_axis_fifo.lxt");
$dumpvars(0, test_axis_fifo);
end
axis_fifo #(
.ADDR_WIDTH(2),
.DATA_WIDTH(8)
)
UUT (
.clk(clk),
.rst(rst),
// AXI input
.input_axis_tdata(input_axis_tdata),
.input_axis_tvalid(input_axis_tvalid),
.input_axis_tready(input_axis_tready),
.input_axis_tlast(input_axis_tlast),
.input_axis_tuser(input_axis_tuser),
// AXI output
.output_axis_tdata(output_axis_tdata),
.output_axis_tvalid(output_axis_tvalid),
.output_axis_tready(output_axis_tready),
.output_axis_tlast(output_axis_tlast),
.output_axis_tuser(output_axis_tuser)
);
endmodule

View File

@ -1,406 +0,0 @@
#!/usr/bin/env python2
"""
Copyright (c) 2014 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""
from myhdl import *
import os
from Queue import Queue
import axis_ep
module = 'axis_fifo_64'
srcs = []
srcs.append("../rtl/%s.v" % module)
srcs.append("test_%s.v" % module)
src = ' '.join(srcs)
build_cmd = "iverilog -o test_%s.vvp %s" % (module, src)
def dut_axis_fifo_64(clk,
rst,
current_test,
input_axis_tdata,
input_axis_tkeep,
input_axis_tvalid,
input_axis_tready,
input_axis_tlast,
input_axis_tuser,
output_axis_tdata,
output_axis_tkeep,
output_axis_tvalid,
output_axis_tready,
output_axis_tlast,
output_axis_tuser):
if os.system(build_cmd):
raise Exception("Error running build command")
return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module,
clk=clk,
rst=rst,
current_test=current_test,
input_axis_tdata=input_axis_tdata,
input_axis_tkeep=input_axis_tkeep,
input_axis_tvalid=input_axis_tvalid,
input_axis_tready=input_axis_tready,
input_axis_tlast=input_axis_tlast,
input_axis_tuser=input_axis_tuser,
output_axis_tdata=output_axis_tdata,
output_axis_tkeep=output_axis_tkeep,
output_axis_tvalid=output_axis_tvalid,
output_axis_tready=output_axis_tready,
output_axis_tlast=output_axis_tlast,
output_axis_tuser=output_axis_tuser)
def bench():
# Inputs
clk = Signal(bool(0))
rst = Signal(bool(0))
current_test = Signal(intbv(0)[8:])
input_axis_tdata = Signal(intbv(0)[64:])
input_axis_tkeep = Signal(intbv(0)[8:])
input_axis_tvalid = Signal(bool(0))
input_axis_tlast = Signal(bool(0))
input_axis_tuser = Signal(bool(0))
output_axis_tready = Signal(bool(0))
# Outputs
input_axis_tready = Signal(bool(0))
output_axis_tdata = Signal(intbv(0)[64:])
output_axis_tkeep = Signal(intbv(0)[8:])
output_axis_tvalid = Signal(bool(0))
output_axis_tlast = Signal(bool(0))
output_axis_tuser = Signal(bool(0))
# sources and sinks
source_queue = Queue()
source_pause = Signal(bool(0))
sink_queue = Queue()
sink_pause = Signal(bool(0))
source = axis_ep.AXIStreamSource(clk,
rst,
tdata=input_axis_tdata,
tkeep=input_axis_tkeep,
tvalid=input_axis_tvalid,
tready=input_axis_tready,
tlast=input_axis_tlast,
tuser=input_axis_tuser,
fifo=source_queue,
pause=source_pause,
name='source')
sink = axis_ep.AXIStreamSink(clk,
rst,
tdata=output_axis_tdata,
tkeep=output_axis_tkeep,
tvalid=output_axis_tvalid,
tready=output_axis_tready,
tlast=output_axis_tlast,
tuser=output_axis_tuser,
fifo=sink_queue,
pause=sink_pause,
name='sink')
# DUT
dut = dut_axis_fifo_64(clk,
rst,
current_test,
input_axis_tdata,
input_axis_tkeep,
input_axis_tvalid,
input_axis_tready,
input_axis_tlast,
input_axis_tuser,
output_axis_tdata,
output_axis_tkeep,
output_axis_tvalid,
output_axis_tready,
output_axis_tlast,
output_axis_tuser)
@always(delay(4))
def clkgen():
clk.next = not clk
@instance
def check():
yield delay(100)
yield clk.posedge
rst.next = 1
yield clk.posedge
rst.next = 0
yield clk.posedge
yield delay(100)
yield clk.posedge
yield clk.posedge
yield clk.posedge
print("test 1: test packet")
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' +
b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
source_queue.put(test_frame)
yield clk.posedge
yield output_axis_tlast.posedge
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame
yield delay(100)
yield clk.posedge
print("test 2: longer packet")
current_test.next = 2
test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
bytearray(range(256)))
source_queue.put(test_frame)
yield clk.posedge
yield output_axis_tlast.posedge
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame
yield clk.posedge
print("test 3: test packet with pauses")
current_test.next = 3
test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
bytearray(range(256)))
source_queue.put(test_frame)
yield clk.posedge
yield delay(64)
yield clk.posedge
source_pause.next = True
yield delay(32)
yield clk.posedge
source_pause.next = False
yield delay(64)
yield clk.posedge
sink_pause.next = True
yield delay(32)
yield clk.posedge
sink_pause.next = False
yield output_axis_tlast.posedge
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame
yield delay(100)
yield clk.posedge
print("test 4: back-to-back packets")
current_test.next = 4
test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
source_queue.put(test_frame1)
source_queue.put(test_frame2)
yield clk.posedge
yield output_axis_tlast.posedge
yield clk.posedge
yield output_axis_tlast.posedge
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame1
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame2
yield delay(100)
yield clk.posedge
print("test 5: alternate pause source")
current_test.next = 5
test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
source_queue.put(test_frame1)
source_queue.put(test_frame2)
yield clk.posedge
while input_axis_tvalid or output_axis_tvalid:
source_pause.next = True
yield clk.posedge
yield clk.posedge
yield clk.posedge
source_pause.next = False
yield clk.posedge
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame1
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame2
yield delay(100)
yield clk.posedge
print("test 6: alternate pause sink")
current_test.next = 6
test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
source_queue.put(test_frame1)
source_queue.put(test_frame2)
yield clk.posedge
while input_axis_tvalid or output_axis_tvalid:
sink_pause.next = True
yield clk.posedge
yield clk.posedge
yield clk.posedge
sink_pause.next = False
yield clk.posedge
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame1
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame2
yield delay(100)
yield clk.posedge
print("test 7: tuser assert")
current_test.next = 7
test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
test_frame.user = 1
source_queue.put(test_frame)
yield clk.posedge
yield output_axis_tlast.posedge
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame
assert rx_frame.user[-1]
yield delay(100)
raise StopSimulation
return dut, source, sink, clkgen, check
def test_bench():
os.chdir(os.path.dirname(os.path.abspath(__file__)))
sim = Simulation(bench())
sim.run()
if __name__ == '__main__':
print("Running test...")
test_bench()

View File

@ -1,97 +0,0 @@
/*
Copyright (c) 2014 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
// Language: Verilog 2001
`timescale 1 ns / 1 ps
module test_axis_fifo_64;
// Inputs
reg clk = 0;
reg rst = 0;
reg [7:0] current_test = 0;
reg [63:0] input_axis_tdata = 0;
reg [7:0] input_axis_tkeep = 0;
reg input_axis_tvalid = 0;
reg input_axis_tlast = 0;
reg input_axis_tuser = 0;
reg output_axis_tready = 0;
// Outputs
wire input_axis_tready;
wire [63:0] output_axis_tdata;
wire [7:0] output_axis_tkeep;
wire output_axis_tvalid;
wire output_axis_tlast;
wire output_axis_tuser;
initial begin
// myhdl integration
$from_myhdl(clk,
rst,
current_test,
input_axis_tdata,
input_axis_tkeep,
input_axis_tvalid,
input_axis_tlast,
input_axis_tuser,
output_axis_tready);
$to_myhdl(input_axis_tready,
output_axis_tdata,
output_axis_tkeep,
output_axis_tvalid,
output_axis_tlast,
output_axis_tuser);
// dump file
$dumpfile("test_axis_fifo_64.lxt");
$dumpvars(0, test_axis_fifo_64);
end
axis_fifo_64 #(
.ADDR_WIDTH(2),
.DATA_WIDTH(64)
)
UUT (
.clk(clk),
.rst(rst),
// AXI input
.input_axis_tdata(input_axis_tdata),
.input_axis_tkeep(input_axis_tkeep),
.input_axis_tvalid(input_axis_tvalid),
.input_axis_tready(input_axis_tready),
.input_axis_tlast(input_axis_tlast),
.input_axis_tuser(input_axis_tuser),
// AXI output
.output_axis_tdata(output_axis_tdata),
.output_axis_tkeep(output_axis_tkeep),
.output_axis_tvalid(output_axis_tvalid),
.output_axis_tready(output_axis_tready),
.output_axis_tlast(output_axis_tlast),
.output_axis_tuser(output_axis_tuser)
);
endmodule

View File

@ -1,555 +0,0 @@
#!/usr/bin/env python2
"""
Copyright (c) 2014 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""
from myhdl import *
import os
from Queue import Queue
import struct
import axis_ep
module = 'axis_frame_join_4'
srcs = []
srcs.append("../rtl/%s.v" % module)
srcs.append("test_%s.v" % module)
src = ' '.join(srcs)
build_cmd = "iverilog -o test_%s.vvp %s" % (module, src)
def dut_axis_frame_join_4(clk,
rst,
current_test,
input_0_axis_tdata,
input_0_axis_tvalid,
input_0_axis_tready,
input_0_axis_tlast,
input_0_axis_tuser,
input_1_axis_tdata,
input_1_axis_tvalid,
input_1_axis_tready,
input_1_axis_tlast,
input_1_axis_tuser,
input_2_axis_tdata,
input_2_axis_tvalid,
input_2_axis_tready,
input_2_axis_tlast,
input_2_axis_tuser,
input_3_axis_tdata,
input_3_axis_tvalid,
input_3_axis_tready,
input_3_axis_tlast,
input_3_axis_tuser,
output_axis_tdata,
output_axis_tvalid,
output_axis_tready,
output_axis_tlast,
output_axis_tuser,
tag,
busy):
if os.system(build_cmd):
raise Exception("Error running build command")
return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module,
clk=clk,
rst=rst,
current_test=current_test,
input_0_axis_tdata=input_0_axis_tdata,
input_0_axis_tvalid=input_0_axis_tvalid,
input_0_axis_tready=input_0_axis_tready,
input_0_axis_tlast=input_0_axis_tlast,
input_0_axis_tuser=input_0_axis_tuser,
input_1_axis_tdata=input_1_axis_tdata,
input_1_axis_tvalid=input_1_axis_tvalid,
input_1_axis_tready=input_1_axis_tready,
input_1_axis_tlast=input_1_axis_tlast,
input_1_axis_tuser=input_1_axis_tuser,
input_2_axis_tdata=input_2_axis_tdata,
input_2_axis_tvalid=input_2_axis_tvalid,
input_2_axis_tready=input_2_axis_tready,
input_2_axis_tlast=input_2_axis_tlast,
input_2_axis_tuser=input_2_axis_tuser,
input_3_axis_tdata=input_3_axis_tdata,
input_3_axis_tvalid=input_3_axis_tvalid,
input_3_axis_tready=input_3_axis_tready,
input_3_axis_tlast=input_3_axis_tlast,
input_3_axis_tuser=input_3_axis_tuser,
output_axis_tdata=output_axis_tdata,
output_axis_tvalid=output_axis_tvalid,
output_axis_tready=output_axis_tready,
output_axis_tlast=output_axis_tlast,
output_axis_tuser=output_axis_tuser,
tag=tag,
busy=busy)
def bench():
# Inputs
clk = Signal(bool(0))
rst = Signal(bool(0))
current_test = Signal(intbv(0)[8:])
input_0_axis_tdata = Signal(intbv(0)[8:])
input_0_axis_tvalid = Signal(bool(0))
input_0_axis_tlast = Signal(bool(0))
input_0_axis_tuser = Signal(bool(0))
input_1_axis_tdata = Signal(intbv(0)[8:])
input_1_axis_tvalid = Signal(bool(0))
input_1_axis_tlast = Signal(bool(0))
input_1_axis_tuser = Signal(bool(0))
input_2_axis_tdata = Signal(intbv(0)[8:])
input_2_axis_tvalid = Signal(bool(0))
input_2_axis_tlast = Signal(bool(0))
input_2_axis_tuser = Signal(bool(0))
input_3_axis_tdata = Signal(intbv(0)[8:])
input_3_axis_tvalid = Signal(bool(0))
input_3_axis_tlast = Signal(bool(0))
input_3_axis_tuser = Signal(bool(0))
output_axis_tready = Signal(bool(0))
tag = Signal(intbv(0)[15:])
# Outputs
input_0_axis_tready = Signal(bool(0))
input_1_axis_tready = Signal(bool(0))
input_2_axis_tready = Signal(bool(0))
input_3_axis_tready = Signal(bool(0))
output_axis_tdata = Signal(intbv(0)[8:])
output_axis_tvalid = Signal(bool(0))
output_axis_tlast = Signal(bool(0))
output_axis_tuser = Signal(bool(0))
busy = Signal(bool(0))
# sources and sinks
source_0_queue = Queue()
source_0_pause = Signal(bool(0))
source_1_queue = Queue()
source_1_pause = Signal(bool(0))
source_2_queue = Queue()
source_2_pause = Signal(bool(0))
source_3_queue = Queue()
source_3_pause = Signal(bool(0))
sink_queue = Queue()
sink_pause = Signal(bool(0))
source_0 = axis_ep.AXIStreamSource(clk,
rst,
tdata=input_0_axis_tdata,
tvalid=input_0_axis_tvalid,
tready=input_0_axis_tready,
tlast=input_0_axis_tlast,
tuser=input_0_axis_tuser,
fifo=source_0_queue,
pause=source_0_pause,
name='source_0')
source_1 = axis_ep.AXIStreamSource(clk,
rst,
tdata=input_1_axis_tdata,
tvalid=input_1_axis_tvalid,
tready=input_1_axis_tready,
tlast=input_1_axis_tlast,
tuser=input_1_axis_tuser,
fifo=source_1_queue,
pause=source_1_pause,
name='source_1')
source_2 = axis_ep.AXIStreamSource(clk,
rst,
tdata=input_2_axis_tdata,
tvalid=input_2_axis_tvalid,
tready=input_2_axis_tready,
tlast=input_2_axis_tlast,
tuser=input_2_axis_tuser,
fifo=source_2_queue,
pause=source_2_pause,
name='source_2')
source_3 = axis_ep.AXIStreamSource(clk,
rst,
tdata=input_3_axis_tdata,
tvalid=input_3_axis_tvalid,
tready=input_3_axis_tready,
tlast=input_3_axis_tlast,
tuser=input_3_axis_tuser,
fifo=source_3_queue,
pause=source_3_pause,
name='source_3')
sink = axis_ep.AXIStreamSink(clk,
rst,
tdata=output_axis_tdata,
tvalid=output_axis_tvalid,
tready=output_axis_tready,
tlast=output_axis_tlast,
tuser=output_axis_tuser,
fifo=sink_queue,
pause=sink_pause,
name='sink')
# DUT
dut = dut_axis_frame_join_4(clk,
rst,
current_test,
input_0_axis_tdata,
input_0_axis_tvalid,
input_0_axis_tready,
input_0_axis_tlast,
input_0_axis_tuser,
input_1_axis_tdata,
input_1_axis_tvalid,
input_1_axis_tready,
input_1_axis_tlast,
input_1_axis_tuser,
input_2_axis_tdata,
input_2_axis_tvalid,
input_2_axis_tready,
input_2_axis_tlast,
input_2_axis_tuser,
input_3_axis_tdata,
input_3_axis_tvalid,
input_3_axis_tready,
input_3_axis_tlast,
input_3_axis_tuser,
output_axis_tdata,
output_axis_tvalid,
output_axis_tready,
output_axis_tlast,
output_axis_tuser,
tag,
busy)
@always(delay(4))
def clkgen():
clk.next = not clk
@instance
def check():
yield delay(100)
yield clk.posedge
rst.next = 1
yield clk.posedge
rst.next = 0
yield clk.posedge
yield delay(100)
yield clk.posedge
yield clk.posedge
tag.next = 1
yield clk.posedge
print("test 1: test packet")
current_test.next = 1
test_frame_0 = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00')
test_frame_1 = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01')
test_frame_2 = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02')
test_frame_3 = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03')
source_0_queue.put(test_frame_0)
source_1_queue.put(test_frame_1)
source_2_queue.put(test_frame_2)
source_3_queue.put(test_frame_3)
yield clk.posedge
yield output_axis_tlast.posedge
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame.data == struct.pack('>H', tag) + test_frame_0.data + test_frame_1.data + test_frame_2.data + test_frame_3.data
yield delay(100)
yield clk.posedge
print("test 2: longer packet")
current_test.next = 2
test_frame_0 = axis_ep.AXIStreamFrame(b'\x00' + bytearray(range(256)) + b'\x00')
test_frame_1 = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01')
test_frame_2 = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02')
test_frame_3 = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03')
source_0_queue.put(test_frame_0)
source_1_queue.put(test_frame_1)
source_2_queue.put(test_frame_2)
source_3_queue.put(test_frame_3)
yield clk.posedge
yield output_axis_tlast.posedge
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame.data == struct.pack('>H', tag) + test_frame_0.data + test_frame_1.data + test_frame_2.data + test_frame_3.data
yield delay(100)
yield clk.posedge
print("test 3: test packet with pauses")
current_test.next = 3
test_frame_0 = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00')
test_frame_1 = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01')
test_frame_2 = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02')
test_frame_3 = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03')
source_0_queue.put(test_frame_0)
source_1_queue.put(test_frame_1)
source_2_queue.put(test_frame_2)
source_3_queue.put(test_frame_3)
yield clk.posedge
yield delay(64)
yield clk.posedge
source_1_pause.next = True
yield delay(32)
yield clk.posedge
source_1_pause.next = False
yield delay(64)
yield clk.posedge
sink_pause.next = True
yield delay(32)
yield clk.posedge
sink_pause.next = False
yield output_axis_tlast.posedge
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame.data == struct.pack('>H', tag) + test_frame_0.data + test_frame_1.data + test_frame_2.data + test_frame_3.data
yield delay(100)
yield clk.posedge
print("test 4: back-to-back packets")
current_test.next = 4
test_frame_0a = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00')
test_frame_0b = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00')
test_frame_1a = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01')
test_frame_1b = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01')
test_frame_2a = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02')
test_frame_2b = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02')
test_frame_3a = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03')
test_frame_3b = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03')
source_0_queue.put(test_frame_0a)
source_0_queue.put(test_frame_0b)
source_1_queue.put(test_frame_1a)
source_1_queue.put(test_frame_1b)
source_2_queue.put(test_frame_2a)
source_2_queue.put(test_frame_2b)
source_3_queue.put(test_frame_3a)
source_3_queue.put(test_frame_3b)
yield clk.posedge
yield output_axis_tlast.posedge
yield clk.posedge
yield output_axis_tlast.posedge
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame.data == struct.pack('>H', tag) + test_frame_0a.data + test_frame_1a.data + test_frame_2a.data + test_frame_3a.data
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame.data == struct.pack('>H', tag) + test_frame_0b.data + test_frame_1b.data + test_frame_2b.data + test_frame_3b.data
yield delay(100)
yield clk.posedge
print("test 5: alternate pause source")
current_test.next = 5
test_frame_0a = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00')
test_frame_0b = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00')
test_frame_1a = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01')
test_frame_1b = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01')
test_frame_2a = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02')
test_frame_2b = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02')
test_frame_3a = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03')
test_frame_3b = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03')
source_0_queue.put(test_frame_0a)
source_0_queue.put(test_frame_0b)
source_1_queue.put(test_frame_1a)
source_1_queue.put(test_frame_1b)
source_2_queue.put(test_frame_2a)
source_2_queue.put(test_frame_2b)
source_3_queue.put(test_frame_3a)
source_3_queue.put(test_frame_3b)
yield clk.posedge
while input_3_axis_tvalid or output_axis_tvalid:
source_0_pause.next = True
source_1_pause.next = True
source_2_pause.next = True
source_3_pause.next = True
yield clk.posedge
yield clk.posedge
yield clk.posedge
source_0_pause.next = False
source_1_pause.next = False
source_2_pause.next = False
source_3_pause.next = False
yield clk.posedge
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame.data == struct.pack('>H', tag) + test_frame_0a.data + test_frame_1a.data + test_frame_2a.data + test_frame_3a.data
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame.data == struct.pack('>H', tag) + test_frame_0b.data + test_frame_1b.data + test_frame_2b.data + test_frame_3b.data
yield delay(100)
yield clk.posedge
print("test 6: alternate pause sink")
current_test.next = 6
test_frame_0a = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00')
test_frame_0b = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00')
test_frame_1a = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01')
test_frame_1b = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01')
test_frame_2a = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02')
test_frame_2b = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02')
test_frame_3a = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03')
test_frame_3b = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03')
source_0_queue.put(test_frame_0a)
source_0_queue.put(test_frame_0b)
source_1_queue.put(test_frame_1a)
source_1_queue.put(test_frame_1b)
source_2_queue.put(test_frame_2a)
source_2_queue.put(test_frame_2b)
source_3_queue.put(test_frame_3a)
source_3_queue.put(test_frame_3b)
yield clk.posedge
while input_3_axis_tvalid or output_axis_tvalid:
sink_pause.next = True
yield clk.posedge
yield clk.posedge
yield clk.posedge
sink_pause.next = False
yield clk.posedge
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame.data == struct.pack('>H', tag) + test_frame_0a.data + test_frame_1a.data + test_frame_2a.data + test_frame_3a.data
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame.data == struct.pack('>H', tag) + test_frame_0b.data + test_frame_1b.data + test_frame_2b.data + test_frame_3b.data
yield delay(100)
yield clk.posedge
print("test 7: tuser assert")
current_test.next = 7
test_frame_0 = axis_ep.AXIStreamFrame(b'\x00\xAA\xBB\xCC\xDD\x00')
test_frame_1 = axis_ep.AXIStreamFrame(b'\x01\xAA\xBB\xCC\xDD\x01')
test_frame_2 = axis_ep.AXIStreamFrame(b'\x02\xAA\xBB\xCC\xDD\x02')
test_frame_3 = axis_ep.AXIStreamFrame(b'\x03\xAA\xBB\xCC\xDD\x03')
test_frame_0.user = 1
source_0_queue.put(test_frame_0)
source_1_queue.put(test_frame_1)
source_2_queue.put(test_frame_2)
source_3_queue.put(test_frame_3)
yield clk.posedge
yield output_axis_tlast.posedge
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame.data == struct.pack('>H', tag) + test_frame_0.data + test_frame_1.data + test_frame_2.data + test_frame_3.data
assert rx_frame.user[-1]
yield delay(100)
raise StopSimulation
return dut, source_0, source_1, source_2, source_3, sink, clkgen, check
def test_bench():
os.chdir(os.path.dirname(os.path.abspath(__file__)))
sim = Simulation(bench())
sim.run()
if __name__ == '__main__':
print("Running test...")
test_bench()

View File

@ -1,143 +0,0 @@
/*
Copyright (c) 2014 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
// Language: Verilog 2001
`timescale 1 ns / 1 ps
module test_axis_frame_join_4;
// Inputs
reg clk = 0;
reg rst = 0;
reg [7:0] current_test = 0;
reg [7:0] input_0_axis_tdata = 8'd0;
reg input_0_axis_tvalid = 1'b0;
reg input_0_axis_tlast = 1'b0;
reg input_0_axis_tuser = 1'b0;
reg [7:0] input_1_axis_tdata = 8'd0;
reg input_1_axis_tvalid = 1'b0;
reg input_1_axis_tlast = 1'b0;
reg input_1_axis_tuser = 1'b0;
reg [7:0] input_2_axis_tdata = 8'd0;
reg input_2_axis_tvalid = 1'b0;
reg input_2_axis_tlast = 1'b0;
reg input_2_axis_tuser = 1'b0;
reg [7:0] input_3_axis_tdata = 8'd0;
reg input_3_axis_tvalid = 1'b0;
reg input_3_axis_tlast = 1'b0;
reg input_3_axis_tuser = 1'b0;
reg output_axis_tready = 1'b0;
reg [15:0] tag = 0;
// Outputs
wire input_0_axis_tready;
wire input_1_axis_tready;
wire input_2_axis_tready;
wire input_3_axis_tready;
wire [7:0] output_axis_tdata;
wire output_axis_tvalid;
wire output_axis_tlast;
wire output_axis_tuser;
wire busy;
initial begin
// myhdl integration
$from_myhdl(clk,
rst,
current_test,
input_0_axis_tdata,
input_0_axis_tvalid,
input_0_axis_tlast,
input_0_axis_tuser,
input_1_axis_tdata,
input_1_axis_tvalid,
input_1_axis_tlast,
input_1_axis_tuser,
input_2_axis_tdata,
input_2_axis_tvalid,
input_2_axis_tlast,
input_2_axis_tuser,
input_3_axis_tdata,
input_3_axis_tvalid,
input_3_axis_tlast,
input_3_axis_tuser,
output_axis_tready,
tag);
$to_myhdl(input_0_axis_tready,
input_1_axis_tready,
input_2_axis_tready,
input_3_axis_tready,
output_axis_tdata,
output_axis_tvalid,
output_axis_tlast,
output_axis_tuser,
busy);
// dump file
$dumpfile("test_axis_frame_join_4.lxt");
$dumpvars(0, test_axis_frame_join_4);
end
axis_frame_join_4 #(
.ENABLE_TAG(1)
)
UUT (
.clk(clk),
.rst(rst),
// axi input
.input_0_axis_tdata(input_0_axis_tdata),
.input_0_axis_tvalid(input_0_axis_tvalid),
.input_0_axis_tready(input_0_axis_tready),
.input_0_axis_tlast(input_0_axis_tlast),
.input_0_axis_tuser(input_0_axis_tuser),
.input_1_axis_tdata(input_1_axis_tdata),
.input_1_axis_tvalid(input_1_axis_tvalid),
.input_1_axis_tready(input_1_axis_tready),
.input_1_axis_tlast(input_1_axis_tlast),
.input_1_axis_tuser(input_1_axis_tuser),
.input_2_axis_tdata(input_2_axis_tdata),
.input_2_axis_tvalid(input_2_axis_tvalid),
.input_2_axis_tready(input_2_axis_tready),
.input_2_axis_tlast(input_2_axis_tlast),
.input_2_axis_tuser(input_2_axis_tuser),
.input_3_axis_tdata(input_3_axis_tdata),
.input_3_axis_tvalid(input_3_axis_tvalid),
.input_3_axis_tready(input_3_axis_tready),
.input_3_axis_tlast(input_3_axis_tlast),
.input_3_axis_tuser(input_3_axis_tuser),
// axi output
.output_axis_tdata(output_axis_tdata),
.output_axis_tvalid(output_axis_tvalid),
.output_axis_tready(output_axis_tready),
.output_axis_tlast(output_axis_tlast),
.output_axis_tuser(output_axis_tuser),
// config
.tag(tag),
// status
.busy(busy)
);
endmodule

View File

@ -1,232 +0,0 @@
#!/usr/bin/env python2
"""
Copyright (c) 2014 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""
from myhdl import *
import os
from Queue import Queue
import axis_ep
import ll_ep
module = 'axis_ll_bridge'
srcs = []
srcs.append("../rtl/%s.v" % module)
srcs.append("test_%s.v" % module)
src = ' '.join(srcs)
build_cmd = "iverilog -o test_%s.vvp %s" % (module, src)
def dut_axis_ll_bridge(clk,
rst,
current_test,
axis_tdata,
axis_tvalid,
axis_tready,
axis_tlast,
ll_data_out,
ll_sof_out_n,
ll_eof_out_n,
ll_src_rdy_out_n,
ll_dst_rdy_in_n):
if os.system(build_cmd):
raise Exception("Error running build command")
return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module,
clk=clk,
rst=rst,
current_test=current_test,
axis_tdata=axis_tdata,
axis_tvalid=axis_tvalid,
axis_tready=axis_tready,
axis_tlast=axis_tlast,
ll_data_out=ll_data_out,
ll_sof_out_n=ll_sof_out_n,
ll_eof_out_n=ll_eof_out_n,
ll_src_rdy_out_n=ll_src_rdy_out_n,
ll_dst_rdy_in_n=ll_dst_rdy_in_n)
def bench():
# Inputs
clk = Signal(bool(0))
rst = Signal(bool(0))
current_test = Signal(intbv(0)[8:])
axis_tdata = Signal(intbv(0)[8:])
axis_tvalid = Signal(bool(0))
axis_tlast = Signal(bool(0))
ll_dst_rdy_in_n = Signal(bool(1))
# Outputs
ll_data_out = Signal(intbv(0)[8:])
ll_sof_out_n = Signal(bool(1))
ll_eof_out_n = Signal(bool(1))
ll_src_rdy_out_n = Signal(bool(1))
axis_tready = Signal(bool(0))
# sources and sinks
source_queue = Queue()
source_pause = Signal(bool(0))
sink_queue = Queue()
sink_pause = Signal(bool(0))
source = axis_ep.AXIStreamSource(clk,
rst,
tdata=axis_tdata,
tvalid=axis_tvalid,
tready=axis_tready,
tlast=axis_tlast,
fifo=source_queue,
pause=source_pause,
name='source')
sink = ll_ep.LocalLinkSink(clk,
rst,
data_in=ll_data_out,
sof_in_n=ll_sof_out_n,
eof_in_n=ll_eof_out_n,
src_rdy_in_n=ll_src_rdy_out_n,
dst_rdy_out_n=ll_dst_rdy_in_n,
fifo=sink_queue,
pause=sink_pause,
name='sink')
# DUT
dut = dut_axis_ll_bridge(clk,
rst,
current_test,
axis_tdata,
axis_tvalid,
axis_tready,
axis_tlast,
ll_data_out,
ll_sof_out_n,
ll_eof_out_n,
ll_src_rdy_out_n,
ll_dst_rdy_in_n)
@always(delay(4))
def clkgen():
clk.next = not clk
@instance
def check():
yield delay(100)
yield clk.posedge
rst.next = 1
yield clk.posedge
rst.next = 0
yield clk.posedge
yield delay(100)
yield clk.posedge
yield clk.posedge
yield clk.posedge
print("test 1: test packet")
current_test.next = 1
source_queue.put(bytearray(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10'))
yield clk.posedge
yield ll_eof_out_n.negedge
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert bytearray(rx_frame) == (b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
yield delay(100)
yield clk.posedge
print("test 2: test packet with pauses")
current_test.next = 2
source_queue.put(bytearray(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10'))
yield clk.posedge
yield delay(64)
yield clk.posedge
source_pause.next = True
yield delay(32)
yield clk.posedge
source_pause.next = False
yield delay(64)
yield clk.posedge
sink_pause.next = True
yield delay(32)
yield clk.posedge
sink_pause.next = False
yield ll_eof_out_n.negedge
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert bytearray(rx_frame) == (b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
yield delay(100)
raise StopSimulation
return dut, source, sink, clkgen, check
def test_bench():
os.chdir(os.path.dirname(os.path.abspath(__file__)))
sim = Simulation(bench())
sim.run()
if __name__ == '__main__':
print("Running test...")
test_bench()

View File

@ -1,85 +0,0 @@
/*
Copyright (c) 2014 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
// Language: Verilog 2001
`timescale 1 ns / 1 ps
module test_axis_ll_bridge;
// Inputs
reg clk = 0;
reg rst = 0;
reg [7:0] current_test = 0;
reg [7:0] axis_tdata = 8'd0;
reg axis_tvalid = 1'b0;
reg axis_tlast = 1'b0;
reg ll_dst_rdy_in_n = 1'b1;
// Outputs
wire [7:0] ll_data_out;
wire ll_sof_out_n;
wire ll_eof_out_n;
wire ll_src_rdy_out_n;
wire axis_tready;
initial begin
// myhdl integration
$from_myhdl(clk,
rst,
current_test,
axis_tdata,
axis_tvalid,
axis_tlast,
ll_dst_rdy_in_n);
$to_myhdl(ll_data_out,
ll_sof_out_n,
ll_eof_out_n,
ll_src_rdy_out_n,
axis_tready);
// dump file
$dumpfile("test_axis_ll_bridge.lxt");
$dumpvars(0, test_axis_ll_bridge);
end
axis_ll_bridge
UUT (
.clk(clk),
.rst(rst),
// axi input
.axis_tdata(axis_tdata),
.axis_tvalid(axis_tvalid),
.axis_tready(axis_tready),
.axis_tlast(axis_tlast),
// locallink output
.ll_data_out(ll_data_out),
.ll_sof_out_n(ll_sof_out_n),
.ll_eof_out_n(ll_eof_out_n),
.ll_src_rdy_out_n(ll_src_rdy_out_n),
.ll_dst_rdy_in_n(ll_dst_rdy_in_n)
);
endmodule

View File

@ -1,532 +0,0 @@
#!/usr/bin/env python2
"""
Copyright (c) 2014 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""
from myhdl import *
import os
from Queue import Queue
import axis_ep
module = 'axis_rate_limit'
srcs = []
srcs.append("../rtl/%s.v" % module)
srcs.append("test_%s.v" % module)
src = ' '.join(srcs)
build_cmd = "iverilog -o test_%s.vvp %s" % (module, src)
def dut_axis_rate_limit(clk,
rst,
current_test,
input_axis_tdata,
input_axis_tvalid,
input_axis_tready,
input_axis_tlast,
input_axis_tuser,
output_axis_tdata,
output_axis_tvalid,
output_axis_tready,
output_axis_tlast,
output_axis_tuser,
rate_num,
rate_denom,
rate_by_frame):
if os.system(build_cmd):
raise Exception("Error running build command")
return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module,
clk=clk,
rst=rst,
current_test=current_test,
input_axis_tdata=input_axis_tdata,
input_axis_tvalid=input_axis_tvalid,
input_axis_tready=input_axis_tready,
input_axis_tlast=input_axis_tlast,
input_axis_tuser=input_axis_tuser,
output_axis_tdata=output_axis_tdata,
output_axis_tvalid=output_axis_tvalid,
output_axis_tready=output_axis_tready,
output_axis_tlast=output_axis_tlast,
output_axis_tuser=output_axis_tuser,
rate_num=rate_num,
rate_denom=rate_denom,
rate_by_frame=rate_by_frame)
def bench():
# Inputs
clk = Signal(bool(0))
rst = Signal(bool(0))
current_test = Signal(intbv(0)[8:])
input_axis_tdata = Signal(intbv(0)[8:])
input_axis_tvalid = Signal(bool(0))
input_axis_tlast = Signal(bool(0))
input_axis_tuser = Signal(bool(0))
output_axis_tready = Signal(bool(0))
rate_num = Signal(intbv(0)[8:])
rate_denom = Signal(intbv(0)[8:])
rate_by_frame = Signal(bool(0))
# Outputs
input_axis_tready = Signal(bool(0))
output_axis_tdata = Signal(intbv(0)[8:])
output_axis_tvalid = Signal(bool(0))
output_axis_tlast = Signal(bool(0))
output_axis_tuser = Signal(bool(0))
# sources and sinks
source_queue = Queue()
source_pause = Signal(bool(0))
sink_queue = Queue()
sink_pause = Signal(bool(0))
source = axis_ep.AXIStreamSource(clk,
rst,
tdata=input_axis_tdata,
tvalid=input_axis_tvalid,
tready=input_axis_tready,
tlast=input_axis_tlast,
tuser=input_axis_tuser,
fifo=source_queue,
pause=source_pause,
name='source')
sink = axis_ep.AXIStreamSink(clk,
rst,
tdata=output_axis_tdata,
tvalid=output_axis_tvalid,
tready=output_axis_tready,
tlast=output_axis_tlast,
tuser=output_axis_tuser,
fifo=sink_queue,
pause=sink_pause,
name='sink')
# DUT
dut = dut_axis_rate_limit(clk,
rst,
current_test,
input_axis_tdata,
input_axis_tvalid,
input_axis_tready,
input_axis_tlast,
input_axis_tuser,
output_axis_tdata,
output_axis_tvalid,
output_axis_tready,
output_axis_tlast,
output_axis_tuser,
rate_num,
rate_denom,
rate_by_frame)
@always(delay(4))
def clkgen():
clk.next = not clk
reset_stats = Signal(bool(False))
cur_frame = Signal(bool(False))
tick_count = Signal(intbv(0))
byte_count = Signal(intbv(0))
frame_count = Signal(intbv(0))
@always(clk.posedge)
def monitor():
ctc = int(tick_count)
cbc = int(byte_count)
cfc = int(frame_count)
if reset_stats:
ctc = 0
cbc = 0
cfc = 0
reset_stats.next = 0
ctc += 1
if output_axis_tready and output_axis_tvalid:
cbc += 1
if output_axis_tlast:
cur_frame.next = False
elif not cur_frame:
cfc += 1
cur_frame.next = True
tick_count.next = ctc
byte_count.next = cbc
frame_count.next = cfc
@instance
def check():
yield delay(100)
yield clk.posedge
rst.next = 1
yield clk.posedge
rst.next = 0
yield clk.posedge
yield delay(100)
yield clk.posedge
yield clk.posedge
rate_num.next = 1
rate_denom.next = 4
rate_by_frame.next = 1
for frame_mode in (True, False):
print("test frame mode %s" % frame_mode)
rate_by_frame.next = frame_mode
rate_num.next = 1
rate_denom.next = 4
yield clk.posedge
print("test 1: test packet")
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' +
b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
source_queue.put(test_frame)
yield clk.posedge
while input_axis_tvalid or output_axis_tvalid:
yield clk.posedge
while not input_axis_tready:
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame
yield delay(100)
yield clk.posedge
print("test 2: longer packet")
current_test.next = 2
test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
bytearray(range(256)))
source_queue.put(test_frame)
yield clk.posedge
while input_axis_tvalid or output_axis_tvalid:
yield clk.posedge
while not input_axis_tready:
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame
yield clk.posedge
print("test 3: test packet with pauses")
current_test.next = 3
test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
bytearray(range(256)))
source_queue.put(test_frame)
yield clk.posedge
yield delay(64)
yield clk.posedge
source_pause.next = True
yield delay(32)
yield clk.posedge
source_pause.next = False
yield delay(64)
yield clk.posedge
sink_pause.next = True
yield delay(32)
yield clk.posedge
sink_pause.next = False
while input_axis_tvalid or output_axis_tvalid:
yield clk.posedge
while not input_axis_tready:
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame
yield delay(100)
yield clk.posedge
print("test 4: back-to-back packets")
current_test.next = 4
test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
source_queue.put(test_frame1)
source_queue.put(test_frame2)
yield clk.posedge
while input_axis_tvalid or output_axis_tvalid:
yield clk.posedge
while not input_axis_tready:
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame1
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame2
yield delay(100)
yield clk.posedge
print("test 5: alternate pause source")
current_test.next = 5
test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
source_queue.put(test_frame1)
source_queue.put(test_frame2)
yield clk.posedge
while input_axis_tvalid or output_axis_tvalid:
source_pause.next = True
yield clk.posedge
yield clk.posedge
yield clk.posedge
source_pause.next = False
yield clk.posedge
while input_axis_tvalid or output_axis_tvalid:
yield clk.posedge
while not input_axis_tready:
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame1
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame2
yield delay(100)
yield clk.posedge
print("test 6: alternate pause sink")
current_test.next = 6
test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
source_queue.put(test_frame1)
source_queue.put(test_frame2)
yield clk.posedge
while input_axis_tvalid or output_axis_tvalid:
sink_pause.next = True
yield clk.posedge
yield clk.posedge
yield clk.posedge
sink_pause.next = False
yield clk.posedge
while input_axis_tvalid or output_axis_tvalid:
yield clk.posedge
while not input_axis_tready:
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame1
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame2
yield delay(100)
yield clk.posedge
print("test 7: tuser assert")
current_test.next = 7
test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
test_frame.user = 1
source_queue.put(test_frame)
yield clk.posedge
while input_axis_tvalid or output_axis_tvalid:
yield clk.posedge
while not input_axis_tready:
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame
assert rx_frame.user[-1]
yield delay(100)
yield clk.posedge
print("test 8: various lengths and delays")
current_test.next = 8
for rate in ((1,1), (1,2), (1,10), (2,3)):
print("test 8 rate %d / %d" % rate)
rate_num.next = rate[0]
rate_denom.next = rate[1]
reset_stats.next = 1
yield clk.posedge
start_time = now()
lens = [32, 48, 64, 96, 128, 256]
test_frame = []
for i in range(len(lens)):
test_frame.append(axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
bytearray(range(lens[i]))))
for f in test_frame:
source_queue.put(f)
yield clk.posedge
yield clk.posedge
while input_axis_tvalid or output_axis_tvalid:
yield clk.posedge
while not input_axis_tready:
yield clk.posedge
stop_time = now()
rx_frame = []
for i in range(len(lens)):
if not sink_queue.empty():
rx_frame.append(sink_queue.get())
assert len(rx_frame) == len(test_frame)
for i in range(len(lens)):
assert rx_frame[i] == test_frame[i]
cycle = (stop_time - start_time) / 8
print("cycles %d" % cycle)
print("tick count %d" % tick_count)
print("byte count %d" % byte_count)
print("frame count %d" % frame_count)
assert tick_count == cycle
assert byte_count == sum(len(f.data) for f in test_frame)
assert frame_count == len(test_frame)
test_rate = 1.0 * rate_num / rate_denom
meas_rate = 1.0 * byte_count / tick_count
error = (test_rate - meas_rate) / test_rate
print("test rate %f" % test_rate)
print("meas rate %f" % meas_rate)
print("error %f%%" % (error*100))
assert abs(error) < 0.1
yield delay(100)
raise StopSimulation
return dut, source, sink, clkgen, monitor, check
def test_bench():
os.chdir(os.path.dirname(os.path.abspath(__file__)))
sim = Simulation(bench())
sim.run()
if __name__ == '__main__':
print("Running test...")
test_bench()

View File

@ -1,100 +0,0 @@
/*
Copyright (c) 2014 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
// Language: Verilog 2001
`timescale 1 ns / 1 ps
module test_axis_rate_limit;
// Inputs
reg clk = 0;
reg rst = 0;
reg [7:0] current_test = 0;
reg [7:0] input_axis_tdata = 8'd0;
reg input_axis_tvalid = 1'b0;
reg input_axis_tlast = 1'b0;
reg input_axis_tuser = 1'b0;
reg output_axis_tready = 1'b0;
reg [7:0] rate_num = 0;
reg [7:0] rate_denom = 0;
reg rate_by_frame = 0;
// Outputs
wire input_axis_tready;
wire [7:0] output_axis_tdata;
wire output_axis_tvalid;
wire output_axis_tlast;
wire output_axis_tuser;
initial begin
// myhdl integration
$from_myhdl(clk,
rst,
current_test,
input_axis_tdata,
input_axis_tvalid,
input_axis_tlast,
input_axis_tuser,
output_axis_tready,
rate_num,
rate_denom,
rate_by_frame);
$to_myhdl(input_axis_tready,
output_axis_tdata,
output_axis_tvalid,
output_axis_tlast,
output_axis_tuser);
// dump file
$dumpfile("test_axis_rate_limit.lxt");
$dumpvars(0, test_axis_rate_limit);
end
axis_rate_limit #(
.DATA_WIDTH(8)
)
UUT (
.clk(clk),
.rst(rst),
// axi input
.input_axis_tdata(input_axis_tdata),
.input_axis_tvalid(input_axis_tvalid),
.input_axis_tready(input_axis_tready),
.input_axis_tlast(input_axis_tlast),
.input_axis_tuser(input_axis_tuser),
// axi output
.output_axis_tdata(output_axis_tdata),
.output_axis_tvalid(output_axis_tvalid),
.output_axis_tready(output_axis_tready),
.output_axis_tlast(output_axis_tlast),
.output_axis_tuser(output_axis_tuser),
// configuration
.rate_num(rate_num),
.rate_denom(rate_denom),
.rate_by_frame(rate_by_frame)
);
endmodule

View File

@ -1,542 +0,0 @@
#!/usr/bin/env python2
"""
Copyright (c) 2014 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""
from myhdl import *
import os
from Queue import Queue
import axis_ep
module = 'axis_rate_limit_64'
srcs = []
srcs.append("../rtl/%s.v" % module)
srcs.append("test_%s.v" % module)
src = ' '.join(srcs)
build_cmd = "iverilog -o test_%s.vvp %s" % (module, src)
def dut_axis_rate_limit_64(clk,
rst,
current_test,
input_axis_tdata,
input_axis_tkeep,
input_axis_tvalid,
input_axis_tready,
input_axis_tlast,
input_axis_tuser,
output_axis_tdata,
output_axis_tkeep,
output_axis_tvalid,
output_axis_tready,
output_axis_tlast,
output_axis_tuser,
rate_num,
rate_denom,
rate_by_frame):
if os.system(build_cmd):
raise Exception("Error running build command")
return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module,
clk=clk,
rst=rst,
current_test=current_test,
input_axis_tdata=input_axis_tdata,
input_axis_tkeep=input_axis_tkeep,
input_axis_tvalid=input_axis_tvalid,
input_axis_tready=input_axis_tready,
input_axis_tlast=input_axis_tlast,
input_axis_tuser=input_axis_tuser,
output_axis_tdata=output_axis_tdata,
output_axis_tkeep=output_axis_tkeep,
output_axis_tvalid=output_axis_tvalid,
output_axis_tready=output_axis_tready,
output_axis_tlast=output_axis_tlast,
output_axis_tuser=output_axis_tuser,
rate_num=rate_num,
rate_denom=rate_denom,
rate_by_frame=rate_by_frame)
def bench():
# Inputs
clk = Signal(bool(0))
rst = Signal(bool(0))
current_test = Signal(intbv(0)[8:])
input_axis_tdata = Signal(intbv(0)[64:])
input_axis_tkeep = Signal(intbv(0)[8:])
input_axis_tvalid = Signal(bool(0))
input_axis_tlast = Signal(bool(0))
input_axis_tuser = Signal(bool(0))
output_axis_tready = Signal(bool(0))
rate_num = Signal(intbv(0)[8:])
rate_denom = Signal(intbv(0)[8:])
rate_by_frame = Signal(bool(0))
# Outputs
input_axis_tready = Signal(bool(0))
output_axis_tdata = Signal(intbv(0)[64:])
output_axis_tkeep = Signal(intbv(0)[8:])
output_axis_tvalid = Signal(bool(0))
output_axis_tlast = Signal(bool(0))
output_axis_tuser = Signal(bool(0))
# sources and sinks
source_queue = Queue()
source_pause = Signal(bool(0))
sink_queue = Queue()
sink_pause = Signal(bool(0))
source = axis_ep.AXIStreamSource(clk,
rst,
tdata=input_axis_tdata,
tkeep=input_axis_tkeep,
tvalid=input_axis_tvalid,
tready=input_axis_tready,
tlast=input_axis_tlast,
tuser=input_axis_tuser,
fifo=source_queue,
pause=source_pause,
name='source')
sink = axis_ep.AXIStreamSink(clk,
rst,
tdata=output_axis_tdata,
tkeep=output_axis_tkeep,
tvalid=output_axis_tvalid,
tready=output_axis_tready,
tlast=output_axis_tlast,
tuser=output_axis_tuser,
fifo=sink_queue,
pause=sink_pause,
name='sink')
# DUT
dut = dut_axis_rate_limit_64(clk,
rst,
current_test,
input_axis_tdata,
input_axis_tkeep,
input_axis_tvalid,
input_axis_tready,
input_axis_tlast,
input_axis_tuser,
output_axis_tdata,
output_axis_tkeep,
output_axis_tvalid,
output_axis_tready,
output_axis_tlast,
output_axis_tuser,
rate_num,
rate_denom,
rate_by_frame)
@always(delay(4))
def clkgen():
clk.next = not clk
reset_stats = Signal(bool(False))
cur_frame = Signal(bool(False))
tick_count = Signal(intbv(0))
byte_count = Signal(intbv(0))
frame_count = Signal(intbv(0))
@always(clk.posedge)
def monitor():
ctc = int(tick_count)
cbc = int(byte_count)
cfc = int(frame_count)
if reset_stats:
ctc = 0
cbc = 0
cfc = 0
reset_stats.next = 0
ctc += len(output_axis_tkeep)
if output_axis_tready and output_axis_tvalid:
cbc += bin(output_axis_tkeep).count('1')
if output_axis_tlast:
cur_frame.next = False
elif not cur_frame:
cfc += 1
cur_frame.next = True
tick_count.next = ctc
byte_count.next = cbc
frame_count.next = cfc
@instance
def check():
yield delay(100)
yield clk.posedge
rst.next = 1
yield clk.posedge
rst.next = 0
yield clk.posedge
yield delay(100)
yield clk.posedge
yield clk.posedge
rate_num.next = 1
rate_denom.next = 4
rate_by_frame.next = 1
for frame_mode in (True, False):
print("test frame mode %s" % frame_mode)
rate_by_frame.next = frame_mode
rate_num.next = 1
rate_denom.next = 4
yield clk.posedge
print("test 1: test packet")
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' +
b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
source_queue.put(test_frame)
yield clk.posedge
while input_axis_tvalid or output_axis_tvalid:
yield clk.posedge
while not input_axis_tready:
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame
yield delay(100)
yield clk.posedge
print("test 2: longer packet")
current_test.next = 2
test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
bytearray(range(256)))
source_queue.put(test_frame)
yield clk.posedge
while input_axis_tvalid or output_axis_tvalid:
yield clk.posedge
while not input_axis_tready:
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame
yield clk.posedge
print("test 3: test packet with pauses")
current_test.next = 3
test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
bytearray(range(256)))
source_queue.put(test_frame)
yield clk.posedge
yield delay(64)
yield clk.posedge
source_pause.next = True
yield delay(32)
yield clk.posedge
source_pause.next = False
yield delay(64)
yield clk.posedge
sink_pause.next = True
yield delay(32)
yield clk.posedge
sink_pause.next = False
while input_axis_tvalid or output_axis_tvalid:
yield clk.posedge
while not input_axis_tready:
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame
yield delay(100)
yield clk.posedge
print("test 4: back-to-back packets")
current_test.next = 4
test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
source_queue.put(test_frame1)
source_queue.put(test_frame2)
yield clk.posedge
while input_axis_tvalid or output_axis_tvalid:
yield clk.posedge
while not input_axis_tready:
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame1
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame2
yield delay(100)
yield clk.posedge
print("test 5: alternate pause source")
current_test.next = 5
test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
source_queue.put(test_frame1)
source_queue.put(test_frame2)
yield clk.posedge
while input_axis_tvalid or output_axis_tvalid:
source_pause.next = True
yield clk.posedge
yield clk.posedge
yield clk.posedge
source_pause.next = False
yield clk.posedge
while input_axis_tvalid or output_axis_tvalid:
yield clk.posedge
while not input_axis_tready:
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame1
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame2
yield delay(100)
yield clk.posedge
print("test 6: alternate pause sink")
current_test.next = 6
test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
source_queue.put(test_frame1)
source_queue.put(test_frame2)
yield clk.posedge
while input_axis_tvalid or output_axis_tvalid:
sink_pause.next = True
yield clk.posedge
yield clk.posedge
yield clk.posedge
sink_pause.next = False
yield clk.posedge
while input_axis_tvalid or output_axis_tvalid:
yield clk.posedge
while not input_axis_tready:
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame1
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame2
yield delay(100)
yield clk.posedge
print("test 7: tuser assert")
current_test.next = 7
test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
test_frame.user = 1
source_queue.put(test_frame)
yield clk.posedge
while input_axis_tvalid or output_axis_tvalid:
yield clk.posedge
while not input_axis_tready:
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame
assert rx_frame.user[-1]
yield delay(100)
yield clk.posedge
print("test 8: various lengths and delays")
current_test.next = 8
for rate in ((1,1), (1,2), (1,10), (2,3)):
print("test 8 rate %d / %d" % rate)
rate_num.next = rate[0]
rate_denom.next = rate[1]
reset_stats.next = 1
yield clk.posedge
start_time = now()
lens = [32, 48, 64, 96, 128, 256]
test_frame = []
for i in range(len(lens)):
test_frame.append(axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
bytearray(range(lens[i]))))
for f in test_frame:
source_queue.put(f)
yield clk.posedge
yield clk.posedge
while input_axis_tvalid or output_axis_tvalid:
yield clk.posedge
while not input_axis_tready:
yield clk.posedge
stop_time = now()
rx_frame = []
for i in range(len(lens)):
if not sink_queue.empty():
rx_frame.append(sink_queue.get())
assert len(rx_frame) == len(test_frame)
for i in range(len(lens)):
assert rx_frame[i] == test_frame[i]
cycle = (stop_time - start_time) / 8
print("cycles %d" % cycle)
print("tick count %d" % tick_count)
print("byte count %d" % byte_count)
print("frame count %d" % frame_count)
assert tick_count == cycle*8
assert byte_count == sum(len(f.data) for f in test_frame)
assert frame_count == len(test_frame)
test_rate = 1.0 * rate_num / rate_denom
meas_rate = 1.0 * byte_count / tick_count
error = (test_rate - meas_rate) / test_rate
print("test rate %f" % test_rate)
print("meas rate %f" % meas_rate)
print("error %f%%" % (error*100))
assert abs(error) < 0.1
yield delay(100)
raise StopSimulation
return dut, source, sink, clkgen, monitor, check
def test_bench():
os.chdir(os.path.dirname(os.path.abspath(__file__)))
sim = Simulation(bench())
sim.run()
if __name__ == '__main__':
print("Running test...")
test_bench()

View File

@ -1,106 +0,0 @@
/*
Copyright (c) 2014 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
// Language: Verilog 2001
`timescale 1 ns / 1 ps
module test_axis_rate_limit_64;
// Inputs
reg clk = 0;
reg rst = 0;
reg [7:0] current_test = 0;
reg [63:0] input_axis_tdata = 8'd0;
reg [7:0] input_axis_tkeep = 8'd0;
reg input_axis_tvalid = 1'b0;
reg input_axis_tlast = 1'b0;
reg input_axis_tuser = 1'b0;
reg output_axis_tready = 1'b0;
reg [7:0] rate_num = 0;
reg [7:0] rate_denom = 0;
reg rate_by_frame = 0;
// Outputs
wire input_axis_tready;
wire [63:0] output_axis_tdata;
wire [7:0] output_axis_tkeep;
wire output_axis_tvalid;
wire output_axis_tlast;
wire output_axis_tuser;
initial begin
// myhdl integration
$from_myhdl(clk,
rst,
current_test,
input_axis_tdata,
input_axis_tkeep,
input_axis_tvalid,
input_axis_tlast,
input_axis_tuser,
output_axis_tready,
rate_num,
rate_denom,
rate_by_frame);
$to_myhdl(input_axis_tready,
output_axis_tdata,
output_axis_tkeep,
output_axis_tvalid,
output_axis_tlast,
output_axis_tuser);
// dump file
$dumpfile("test_axis_rate_limit_64.lxt");
$dumpvars(0, test_axis_rate_limit_64);
end
axis_rate_limit_64 #(
.DATA_WIDTH(64)
)
UUT (
.clk(clk),
.rst(rst),
// axi input
.input_axis_tdata(input_axis_tdata),
.input_axis_tkeep(input_axis_tkeep),
.input_axis_tvalid(input_axis_tvalid),
.input_axis_tready(input_axis_tready),
.input_axis_tlast(input_axis_tlast),
.input_axis_tuser(input_axis_tuser),
// axi output
.output_axis_tdata(output_axis_tdata),
.output_axis_tkeep(output_axis_tkeep),
.output_axis_tvalid(output_axis_tvalid),
.output_axis_tready(output_axis_tready),
.output_axis_tlast(output_axis_tlast),
.output_axis_tuser(output_axis_tuser),
// configuration
.rate_num(rate_num),
.rate_denom(rate_denom),
.rate_by_frame(rate_by_frame)
);
endmodule

View File

@ -1,396 +0,0 @@
#!/usr/bin/env python2
"""
Copyright (c) 2014 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""
from myhdl import *
import os
from Queue import Queue
import axis_ep
module = 'axis_register'
srcs = []
srcs.append("../rtl/%s.v" % module)
srcs.append("test_%s.v" % module)
src = ' '.join(srcs)
build_cmd = "iverilog -o test_%s.vvp %s" % (module, src)
def dut_axis_register(clk,
rst,
current_test,
input_axis_tdata,
input_axis_tvalid,
input_axis_tready,
input_axis_tlast,
input_axis_tuser,
output_axis_tdata,
output_axis_tvalid,
output_axis_tready,
output_axis_tlast,
output_axis_tuser):
if os.system(build_cmd):
raise Exception("Error running build command")
return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module,
clk=clk,
rst=rst,
current_test=current_test,
input_axis_tdata=input_axis_tdata,
input_axis_tvalid=input_axis_tvalid,
input_axis_tready=input_axis_tready,
input_axis_tlast=input_axis_tlast,
input_axis_tuser=input_axis_tuser,
output_axis_tdata=output_axis_tdata,
output_axis_tvalid=output_axis_tvalid,
output_axis_tready=output_axis_tready,
output_axis_tlast=output_axis_tlast,
output_axis_tuser=output_axis_tuser)
def bench():
# Inputs
clk = Signal(bool(0))
rst = Signal(bool(0))
current_test = Signal(intbv(0)[8:])
input_axis_tdata = Signal(intbv(0)[8:])
input_axis_tvalid = Signal(bool(0))
input_axis_tlast = Signal(bool(0))
input_axis_tuser = Signal(bool(0))
output_axis_tready = Signal(bool(0))
# Outputs
input_axis_tready = Signal(bool(0))
output_axis_tdata = Signal(intbv(0)[8:])
output_axis_tvalid = Signal(bool(0))
output_axis_tlast = Signal(bool(0))
output_axis_tuser = Signal(bool(0))
# sources and sinks
source_queue = Queue()
source_pause = Signal(bool(0))
sink_queue = Queue()
sink_pause = Signal(bool(0))
source = axis_ep.AXIStreamSource(clk,
rst,
tdata=input_axis_tdata,
tvalid=input_axis_tvalid,
tready=input_axis_tready,
tlast=input_axis_tlast,
tuser=input_axis_tuser,
fifo=source_queue,
pause=source_pause,
name='source')
sink = axis_ep.AXIStreamSink(clk,
rst,
tdata=output_axis_tdata,
tvalid=output_axis_tvalid,
tready=output_axis_tready,
tlast=output_axis_tlast,
tuser=output_axis_tuser,
fifo=sink_queue,
pause=sink_pause,
name='sink')
# DUT
dut = dut_axis_register(clk,
rst,
current_test,
input_axis_tdata,
input_axis_tvalid,
input_axis_tready,
input_axis_tlast,
input_axis_tuser,
output_axis_tdata,
output_axis_tvalid,
output_axis_tready,
output_axis_tlast,
output_axis_tuser)
@always(delay(4))
def clkgen():
clk.next = not clk
@instance
def check():
yield delay(100)
yield clk.posedge
rst.next = 1
yield clk.posedge
rst.next = 0
yield clk.posedge
yield delay(100)
yield clk.posedge
yield clk.posedge
yield clk.posedge
print("test 1: test packet")
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' +
b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
source_queue.put(test_frame)
yield clk.posedge
yield output_axis_tlast.posedge
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame
yield delay(100)
yield clk.posedge
print("test 2: longer packet")
current_test.next = 2
test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
bytearray(range(256)))
source_queue.put(test_frame)
yield clk.posedge
yield output_axis_tlast.posedge
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame
yield clk.posedge
print("test 3: test packet with pauses")
current_test.next = 3
test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
source_queue.put(test_frame)
yield clk.posedge
yield delay(64)
yield clk.posedge
source_pause.next = True
yield delay(32)
yield clk.posedge
source_pause.next = False
yield delay(64)
yield clk.posedge
sink_pause.next = True
yield delay(32)
yield clk.posedge
sink_pause.next = False
yield output_axis_tlast.posedge
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame
yield delay(100)
yield clk.posedge
print("test 4: back-to-back packets")
current_test.next = 4
test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
source_queue.put(test_frame1)
source_queue.put(test_frame2)
yield clk.posedge
yield output_axis_tlast.posedge
yield clk.posedge
yield output_axis_tlast.posedge
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame1
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame2
yield delay(100)
yield clk.posedge
print("test 5: alternate pause source")
current_test.next = 5
test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
source_queue.put(test_frame1)
source_queue.put(test_frame2)
yield clk.posedge
while input_axis_tvalid or output_axis_tvalid:
source_pause.next = True
yield clk.posedge
yield clk.posedge
yield clk.posedge
source_pause.next = False
yield clk.posedge
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame1
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame2
yield delay(100)
yield clk.posedge
print("test 6: alternate pause sink")
current_test.next = 6
test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
source_queue.put(test_frame1)
source_queue.put(test_frame2)
yield clk.posedge
while input_axis_tvalid or output_axis_tvalid:
sink_pause.next = True
yield clk.posedge
yield clk.posedge
yield clk.posedge
sink_pause.next = False
yield clk.posedge
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame1
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame2
yield delay(100)
yield clk.posedge
print("test 7: tuser assert")
current_test.next = 7
test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
test_frame.user = 1
source_queue.put(test_frame)
yield clk.posedge
yield output_axis_tlast.posedge
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame
assert rx_frame.user[-1]
yield delay(100)
raise StopSimulation
return dut, source, sink, clkgen, check
def test_bench():
os.chdir(os.path.dirname(os.path.abspath(__file__)))
sim = Simulation(bench())
sim.run()
if __name__ == '__main__':
print("Running test...")
test_bench()

View File

@ -1,90 +0,0 @@
/*
Copyright (c) 2014 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
// Language: Verilog 2001
`timescale 1 ns / 1 ps
module test_axis_register;
// Inputs
reg clk = 0;
reg rst = 0;
reg [7:0] current_test = 0;
reg [7:0] input_axis_tdata = 8'd0;
reg input_axis_tvalid = 1'b0;
reg input_axis_tlast = 1'b0;
reg input_axis_tuser = 1'b0;
reg output_axis_tready = 1'b0;
// Outputs
wire input_axis_tready;
wire [7:0] output_axis_tdata;
wire output_axis_tvalid;
wire output_axis_tlast;
wire output_axis_tuser;
initial begin
// myhdl integration
$from_myhdl(clk,
rst,
current_test,
input_axis_tdata,
input_axis_tvalid,
input_axis_tlast,
input_axis_tuser,
output_axis_tready);
$to_myhdl(input_axis_tready,
output_axis_tdata,
output_axis_tvalid,
output_axis_tlast,
output_axis_tuser);
// dump file
$dumpfile("test_axis_register.lxt");
$dumpvars(0, test_axis_register);
end
axis_register #(
.DATA_WIDTH(8)
)
UUT (
.clk(clk),
.rst(rst),
// axi input
.input_axis_tdata(input_axis_tdata),
.input_axis_tvalid(input_axis_tvalid),
.input_axis_tready(input_axis_tready),
.input_axis_tlast(input_axis_tlast),
.input_axis_tuser(input_axis_tuser),
// axi output
.output_axis_tdata(output_axis_tdata),
.output_axis_tvalid(output_axis_tvalid),
.output_axis_tready(output_axis_tready),
.output_axis_tlast(output_axis_tlast),
.output_axis_tuser(output_axis_tuser)
);
endmodule

View File

@ -1,406 +0,0 @@
#!/usr/bin/env python2
"""
Copyright (c) 2014 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""
from myhdl import *
import os
from Queue import Queue
import axis_ep
module = 'axis_register_64'
srcs = []
srcs.append("../rtl/%s.v" % module)
srcs.append("test_%s.v" % module)
src = ' '.join(srcs)
build_cmd = "iverilog -o test_%s.vvp %s" % (module, src)
def dut_axis_register_64(clk,
rst,
current_test,
input_axis_tdata,
input_axis_tkeep,
input_axis_tvalid,
input_axis_tready,
input_axis_tlast,
input_axis_tuser,
output_axis_tdata,
output_axis_tkeep,
output_axis_tvalid,
output_axis_tready,
output_axis_tlast,
output_axis_tuser):
if os.system(build_cmd):
raise Exception("Error running build command")
return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module,
clk=clk,
rst=rst,
current_test=current_test,
input_axis_tdata=input_axis_tdata,
input_axis_tkeep=input_axis_tkeep,
input_axis_tvalid=input_axis_tvalid,
input_axis_tready=input_axis_tready,
input_axis_tlast=input_axis_tlast,
input_axis_tuser=input_axis_tuser,
output_axis_tdata=output_axis_tdata,
output_axis_tkeep=output_axis_tkeep,
output_axis_tvalid=output_axis_tvalid,
output_axis_tready=output_axis_tready,
output_axis_tlast=output_axis_tlast,
output_axis_tuser=output_axis_tuser)
def bench():
# Inputs
clk = Signal(bool(0))
rst = Signal(bool(0))
current_test = Signal(intbv(0)[8:])
input_axis_tdata = Signal(intbv(0)[64:])
input_axis_tkeep = Signal(intbv(0)[8:])
input_axis_tvalid = Signal(bool(0))
input_axis_tlast = Signal(bool(0))
input_axis_tuser = Signal(bool(0))
output_axis_tready = Signal(bool(0))
# Outputs
input_axis_tready = Signal(bool(0))
output_axis_tdata = Signal(intbv(0)[64:])
output_axis_tkeep = Signal(intbv(0)[8:])
output_axis_tvalid = Signal(bool(0))
output_axis_tlast = Signal(bool(0))
output_axis_tuser = Signal(bool(0))
# sources and sinks
source_queue = Queue()
source_pause = Signal(bool(0))
sink_queue = Queue()
sink_pause = Signal(bool(0))
source = axis_ep.AXIStreamSource(clk,
rst,
tdata=input_axis_tdata,
tkeep=input_axis_tkeep,
tvalid=input_axis_tvalid,
tready=input_axis_tready,
tlast=input_axis_tlast,
tuser=input_axis_tuser,
fifo=source_queue,
pause=source_pause,
name='source')
sink = axis_ep.AXIStreamSink(clk,
rst,
tdata=output_axis_tdata,
tkeep=output_axis_tkeep,
tvalid=output_axis_tvalid,
tready=output_axis_tready,
tlast=output_axis_tlast,
tuser=output_axis_tuser,
fifo=sink_queue,
pause=sink_pause,
name='sink')
# DUT
dut = dut_axis_register_64(clk,
rst,
current_test,
input_axis_tdata,
input_axis_tkeep,
input_axis_tvalid,
input_axis_tready,
input_axis_tlast,
input_axis_tuser,
output_axis_tdata,
output_axis_tkeep,
output_axis_tvalid,
output_axis_tready,
output_axis_tlast,
output_axis_tuser)
@always(delay(4))
def clkgen():
clk.next = not clk
@instance
def check():
yield delay(100)
yield clk.posedge
rst.next = 1
yield clk.posedge
rst.next = 0
yield clk.posedge
yield delay(100)
yield clk.posedge
yield clk.posedge
yield clk.posedge
print("test 1: test packet")
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' +
b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
source_queue.put(test_frame)
yield clk.posedge
yield output_axis_tlast.posedge
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame
yield delay(100)
yield clk.posedge
print("test 2: longer packet")
current_test.next = 2
test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
bytearray(range(256)))
source_queue.put(test_frame)
yield clk.posedge
yield output_axis_tlast.posedge
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame
yield clk.posedge
print("test 3: test packet with pauses")
current_test.next = 3
test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
bytearray(range(256)))
source_queue.put(test_frame)
yield clk.posedge
yield delay(64)
yield clk.posedge
source_pause.next = True
yield delay(32)
yield clk.posedge
source_pause.next = False
yield delay(64)
yield clk.posedge
sink_pause.next = True
yield delay(32)
yield clk.posedge
sink_pause.next = False
yield output_axis_tlast.posedge
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame
yield delay(100)
yield clk.posedge
print("test 4: back-to-back packets")
current_test.next = 4
test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
source_queue.put(test_frame1)
source_queue.put(test_frame2)
yield clk.posedge
yield output_axis_tlast.posedge
yield clk.posedge
yield output_axis_tlast.posedge
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame1
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame2
yield delay(100)
yield clk.posedge
print("test 5: alternate pause source")
current_test.next = 5
test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
source_queue.put(test_frame1)
source_queue.put(test_frame2)
yield clk.posedge
while input_axis_tvalid or output_axis_tvalid:
source_pause.next = True
yield clk.posedge
yield clk.posedge
yield clk.posedge
source_pause.next = False
yield clk.posedge
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame1
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame2
yield delay(100)
yield clk.posedge
print("test 6: alternate pause sink")
current_test.next = 6
test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
source_queue.put(test_frame1)
source_queue.put(test_frame2)
yield clk.posedge
while input_axis_tvalid or output_axis_tvalid:
sink_pause.next = True
yield clk.posedge
yield clk.posedge
yield clk.posedge
sink_pause.next = False
yield clk.posedge
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame1
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame2
yield delay(100)
yield clk.posedge
print("test 7: tuser assert")
current_test.next = 7
test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
test_frame.user = 1
source_queue.put(test_frame)
yield clk.posedge
yield output_axis_tlast.posedge
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert rx_frame == test_frame
assert rx_frame.user[-1]
yield delay(100)
raise StopSimulation
return dut, source, sink, clkgen, check
def test_bench():
os.chdir(os.path.dirname(os.path.abspath(__file__)))
sim = Simulation(bench())
sim.run()
if __name__ == '__main__':
print("Running test...")
test_bench()

View File

@ -1,96 +0,0 @@
/*
Copyright (c) 2014 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
// Language: Verilog 2001
`timescale 1 ns / 1 ps
module test_axis_register_64;
// Inputs
reg clk = 0;
reg rst = 0;
reg [7:0] current_test = 0;
reg [63:0] input_axis_tdata = 8'd0;
reg [7:0] input_axis_tkeep = 8'd0;
reg input_axis_tvalid = 1'b0;
reg input_axis_tlast = 1'b0;
reg input_axis_tuser = 1'b0;
reg output_axis_tready = 1'b0;
// Outputs
wire input_axis_tready;
wire [63:0] output_axis_tdata;
wire [7:0] output_axis_tkeep;
wire output_axis_tvalid;
wire output_axis_tlast;
wire output_axis_tuser;
initial begin
// myhdl integration
$from_myhdl(clk,
rst,
current_test,
input_axis_tdata,
input_axis_tkeep,
input_axis_tvalid,
input_axis_tlast,
input_axis_tuser,
output_axis_tready);
$to_myhdl(input_axis_tready,
output_axis_tdata,
output_axis_tkeep,
output_axis_tvalid,
output_axis_tlast,
output_axis_tuser);
// dump file
$dumpfile("test_axis_register_64.lxt");
$dumpvars(0, test_axis_register_64);
end
axis_register_64 #(
.DATA_WIDTH(64)
)
UUT (
.clk(clk),
.rst(rst),
// axi input
.input_axis_tdata(input_axis_tdata),
.input_axis_tkeep(input_axis_tkeep),
.input_axis_tvalid(input_axis_tvalid),
.input_axis_tready(input_axis_tready),
.input_axis_tlast(input_axis_tlast),
.input_axis_tuser(input_axis_tuser),
// axi output
.output_axis_tdata(output_axis_tdata),
.output_axis_tkeep(output_axis_tkeep),
.output_axis_tvalid(output_axis_tvalid),
.output_axis_tready(output_axis_tready),
.output_axis_tlast(output_axis_tlast),
.output_axis_tuser(output_axis_tuser)
);
endmodule

View File

@ -1,792 +0,0 @@
#!/usr/bin/env python2
"""
Copyright (c) 2014 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""
from myhdl import *
import os
from Queue import Queue
import struct
import axis_ep
module = 'axis_stat_counter'
srcs = []
srcs.append("../rtl/%s.v" % module)
srcs.append("test_%s.v" % module)
src = ' '.join(srcs)
build_cmd = "iverilog -o test_%s.vvp %s" % (module, src)
def dut_axis_stat_counter(clk,
rst,
current_test,
monitor_axis_tdata,
monitor_axis_tkeep,
monitor_axis_tvalid,
monitor_axis_tready,
monitor_axis_tlast,
monitor_axis_tuser,
output_axis_tdata,
output_axis_tvalid,
output_axis_tready,
output_axis_tlast,
output_axis_tuser,
tag,
trigger,
busy):
if os.system(build_cmd):
raise Exception("Error running build command")
return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module,
clk=clk,
rst=rst,
current_test=current_test,
monitor_axis_tdata=monitor_axis_tdata,
monitor_axis_tkeep=monitor_axis_tkeep,
monitor_axis_tvalid=monitor_axis_tvalid,
monitor_axis_tready=monitor_axis_tready,
monitor_axis_tlast=monitor_axis_tlast,
monitor_axis_tuser=monitor_axis_tuser,
output_axis_tdata=output_axis_tdata,
output_axis_tvalid=output_axis_tvalid,
output_axis_tready=output_axis_tready,
output_axis_tlast=output_axis_tlast,
output_axis_tuser=output_axis_tuser,
tag=tag,
trigger=trigger,
busy=busy)
def bench():
# Inputs
clk = Signal(bool(0))
rst = Signal(bool(0))
current_test = Signal(intbv(0)[8:])
monitor_axis_tdata = Signal(intbv(0)[64:])
monitor_axis_tkeep = Signal(intbv(0)[8:])
monitor_axis_tvalid = Signal(bool(0))
monitor_axis_tready = Signal(bool(0))
monitor_axis_tlast = Signal(bool(0))
monitor_axis_tuser = Signal(bool(0))
output_axis_tready = Signal(bool(0))
tag = Signal(intbv(16)[16:])
trigger = Signal(bool(0))
# Outputs
output_axis_tdata = Signal(intbv(0)[8:])
output_axis_tvalid = Signal(bool(0))
output_axis_tlast = Signal(bool(0))
output_axis_tuser = Signal(bool(0))
busy = Signal(bool(0))
# sources and sinks
source_queue = Queue()
source_pause = Signal(bool(0))
monitor_sink_queue = Queue()
monitor_sink_pause = Signal(bool(0))
sink_queue = Queue()
sink_pause = Signal(bool(0))
source = axis_ep.AXIStreamSource(clk,
rst,
tdata=monitor_axis_tdata,
tkeep=monitor_axis_tkeep,
tvalid=monitor_axis_tvalid,
tready=monitor_axis_tready,
tlast=monitor_axis_tlast,
tuser=monitor_axis_tuser,
fifo=source_queue,
pause=source_pause,
name='source')
monitor_sink = axis_ep.AXIStreamSink(clk,
rst,
tdata=monitor_axis_tdata,
tkeep=monitor_axis_tkeep,
tvalid=monitor_axis_tvalid,
tready=monitor_axis_tready,
tlast=monitor_axis_tlast,
tuser=monitor_axis_tuser,
fifo=monitor_sink_queue,
pause=monitor_sink_pause,
name='monitor_sink')
sink = axis_ep.AXIStreamSink(clk,
rst,
tdata=output_axis_tdata,
tvalid=output_axis_tvalid,
tready=output_axis_tready,
tlast=output_axis_tlast,
tuser=output_axis_tuser,
fifo=sink_queue,
pause=sink_pause,
name='sink')
# DUT
dut = dut_axis_stat_counter(clk,
rst,
current_test,
monitor_axis_tdata,
monitor_axis_tkeep,
monitor_axis_tvalid,
monitor_axis_tready,
monitor_axis_tlast,
monitor_axis_tuser,
output_axis_tdata,
output_axis_tvalid,
output_axis_tready,
output_axis_tlast,
output_axis_tuser,
tag,
trigger,
busy)
@always(delay(4))
def clkgen():
clk.next = not clk
@instance
def check():
yield delay(100)
yield clk.posedge
rst.next = 1
yield clk.posedge
rst.next = 0
yield clk.posedge
yield delay(100)
yield clk.posedge
yield clk.posedge
tag.next = 1
yield clk.posedge
print("test 1: test tick timer")
current_test.next = 1
yield clk.posedge
start_time = now()
trigger.next = 1
yield clk.posedge
trigger.next = 0
for i in range(100-1):
yield clk.posedge
stop_time = now()
trigger.next = 1
yield clk.posedge
trigger.next = 0
yield clk.posedge
while output_axis_tvalid:
yield clk.posedge
yield clk.posedge
yield clk.posedge
# discard first trigger output
if not sink_queue.empty():
rx_frame = sink_queue.get()
# check second trigger output
if not sink_queue.empty():
rx_frame = sink_queue.get()
rx_frame_values = struct.unpack(">HLLL", rx_frame.data)
cycles = (stop_time - start_time) / 8
print(rx_frame_values)
assert rx_frame_values[0] == 1
assert rx_frame_values[1] == cycles*8
assert rx_frame_values[1] == 100*8
yield delay(100)
yield clk.posedge
print("test 2: pause sink")
current_test.next = 2
yield clk.posedge
start_time = now()
trigger.next = 1
yield clk.posedge
trigger.next = 0
for i in range(100-1):
yield clk.posedge
stop_time = now()
trigger.next = 1
yield clk.posedge
trigger.next = 0
while trigger or output_axis_tvalid:
sink_pause.next = True
yield clk.posedge
yield clk.posedge
yield clk.posedge
sink_pause.next = False
yield clk.posedge
yield clk.posedge
yield clk.posedge
# discard first trigger output
if not sink_queue.empty():
rx_frame = sink_queue.get()
# check second trigger output
if not sink_queue.empty():
rx_frame = sink_queue.get()
rx_frame_values = struct.unpack(">HLLL", rx_frame.data)
cycles = (stop_time - start_time) / 8
print(rx_frame_values)
assert rx_frame_values[0] == 1
assert rx_frame_values[1] == cycles*8
assert rx_frame_values[1] == 100*8
yield delay(100)
yield clk.posedge
print("test 3: test packet")
current_test.next = 3
yield clk.posedge
start_time = now()
trigger.next = 1
yield clk.posedge
trigger.next = 0
test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
source_queue.put(test_frame)
yield clk.posedge
while monitor_axis_tvalid:
yield clk.posedge
while output_axis_tvalid:
yield clk.posedge
yield clk.posedge
stop_time = now()
trigger.next = 1
yield clk.posedge
trigger.next = 0
yield clk.posedge
while output_axis_tvalid:
yield clk.posedge
yield clk.posedge
yield clk.posedge
# discard first trigger output
if not sink_queue.empty():
rx_frame = sink_queue.get()
# check second trigger output
if not sink_queue.empty():
rx_frame = sink_queue.get()
rx_frame_values = struct.unpack(">HLLL", rx_frame.data)
cycles = (stop_time - start_time) / 8
print(rx_frame_values)
assert rx_frame_values[0] == 1
assert rx_frame_values[1] == cycles*8
assert rx_frame_values[2] == len(test_frame.data)
assert rx_frame_values[3] == 1
yield delay(100)
yield clk.posedge
print("test 4: longer packet")
current_test.next = 4
yield clk.posedge
start_time = now()
trigger.next = 1
yield clk.posedge
trigger.next = 0
test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
bytearray(range(256)))
source_queue.put(test_frame)
yield clk.posedge
while monitor_axis_tvalid:
yield clk.posedge
while output_axis_tvalid:
yield clk.posedge
yield clk.posedge
stop_time = now()
trigger.next = 1
yield clk.posedge
trigger.next = 0
yield clk.posedge
while output_axis_tvalid:
yield clk.posedge
yield clk.posedge
yield clk.posedge
# discard first trigger output
if not sink_queue.empty():
rx_frame = sink_queue.get()
# check second trigger output
if not sink_queue.empty():
rx_frame = sink_queue.get()
rx_frame_values = struct.unpack(">HLLL", rx_frame.data)
cycles = (stop_time - start_time) / 8
print(rx_frame_values)
assert rx_frame_values[0] == 1
assert rx_frame_values[1] == cycles*8
assert rx_frame_values[2] == len(test_frame.data)
assert rx_frame_values[3] == 1
yield delay(100)
yield clk.posedge
print("test 5: test packet with pauses")
current_test.next = 5
yield clk.posedge
start_time = now()
trigger.next = 1
yield clk.posedge
trigger.next = 0
test_frame = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
bytearray(range(256)))
source_queue.put(test_frame)
yield clk.posedge
yield delay(64)
yield clk.posedge
source_pause.next = True
yield delay(32)
yield clk.posedge
source_pause.next = False
yield delay(64)
yield clk.posedge
monitor_sink_pause.next = True
yield delay(32)
yield clk.posedge
monitor_sink_pause.next = False
while monitor_axis_tvalid:
yield clk.posedge
while output_axis_tvalid:
yield clk.posedge
yield clk.posedge
stop_time = now()
trigger.next = 1
yield clk.posedge
trigger.next = 0
yield clk.posedge
while output_axis_tvalid:
yield clk.posedge
yield clk.posedge
yield clk.posedge
# discard first trigger output
if not sink_queue.empty():
rx_frame = sink_queue.get()
# check second trigger output
if not sink_queue.empty():
rx_frame = sink_queue.get()
rx_frame_values = struct.unpack(">HLLL", rx_frame.data)
cycles = (stop_time - start_time) / 8
print(rx_frame_values)
assert rx_frame_values[0] == 1
assert rx_frame_values[1] == cycles*8
assert rx_frame_values[2] == len(test_frame.data)
assert rx_frame_values[3] == 1
yield delay(100)
yield clk.posedge
print("test 6: back-to-back packets")
current_test.next = 6
yield clk.posedge
start_time = now()
trigger.next = 1
yield clk.posedge
trigger.next = 0
test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
source_queue.put(test_frame1)
source_queue.put(test_frame2)
yield clk.posedge
while monitor_axis_tvalid:
yield clk.posedge
while output_axis_tvalid:
yield clk.posedge
yield clk.posedge
stop_time = now()
trigger.next = 1
yield clk.posedge
trigger.next = 0
yield clk.posedge
while output_axis_tvalid:
yield clk.posedge
yield clk.posedge
yield clk.posedge
# discard first trigger output
if not sink_queue.empty():
rx_frame = sink_queue.get()
# check second trigger output
if not sink_queue.empty():
rx_frame = sink_queue.get()
rx_frame_values = struct.unpack(">HLLL", rx_frame.data)
cycles = (stop_time - start_time) / 8
print(rx_frame_values)
assert rx_frame_values[0] == 1
assert rx_frame_values[1] == cycles*8
assert rx_frame_values[2] == len(test_frame1.data) + len(test_frame2.data)
assert rx_frame_values[3] == 2
yield delay(100)
yield clk.posedge
print("test 7: alternate pause source")
current_test.next = 7
yield clk.posedge
start_time = now()
trigger.next = 1
yield clk.posedge
trigger.next = 0
test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
source_queue.put(test_frame1)
source_queue.put(test_frame2)
yield clk.posedge
while monitor_axis_tvalid:
yield clk.posedge
while output_axis_tvalid:
yield clk.posedge
yield clk.posedge
stop_time = now()
trigger.next = 1
yield clk.posedge
trigger.next = 0
yield clk.posedge
while output_axis_tvalid:
yield clk.posedge
yield clk.posedge
yield clk.posedge
# discard first trigger output
if not sink_queue.empty():
rx_frame = sink_queue.get()
# check second trigger output
if not sink_queue.empty():
rx_frame = sink_queue.get()
rx_frame_values = struct.unpack(">HLLL", rx_frame.data)
cycles = (stop_time - start_time) / 8
print(rx_frame_values)
assert rx_frame_values[0] == 1
assert rx_frame_values[1] == cycles*8
assert rx_frame_values[2] == len(test_frame1.data) + len(test_frame2.data)
assert rx_frame_values[3] == 2
yield delay(100)
yield clk.posedge
print("test 8: alternate pause sink")
current_test.next = 8
yield clk.posedge
start_time = now()
trigger.next = 1
yield clk.posedge
trigger.next = 0
test_frame1 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
test_frame2 = axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x02\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
source_queue.put(test_frame1)
source_queue.put(test_frame2)
yield clk.posedge
while monitor_axis_tvalid:
yield clk.posedge
while output_axis_tvalid:
yield clk.posedge
yield clk.posedge
stop_time = now()
trigger.next = 1
yield clk.posedge
trigger.next = 0
yield clk.posedge
while output_axis_tvalid:
yield clk.posedge
yield clk.posedge
yield clk.posedge
# discard first trigger output
if not sink_queue.empty():
rx_frame = sink_queue.get()
# check second trigger output
if not sink_queue.empty():
rx_frame = sink_queue.get()
rx_frame_values = struct.unpack(">HLLL", rx_frame.data)
cycles = (stop_time - start_time) / 8
print(rx_frame_values)
assert rx_frame_values[0] == 1
assert rx_frame_values[1] == cycles*8
assert rx_frame_values[2] == len(test_frame1.data) + len(test_frame2.data)
assert rx_frame_values[3] == 2
yield delay(100)
yield clk.posedge
print("test 9: various length packets")
current_test.next = 9
yield clk.posedge
start_time = now()
trigger.next = 1
yield clk.posedge
trigger.next = 0
lens = [32, 48, 96, 128, 256]
test_frame = []
for i in range(len(lens)):
test_frame.append(axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
bytearray(range(lens[i]))))
for f in test_frame:
source_queue.put(f)
yield clk.posedge
while monitor_axis_tvalid:
yield clk.posedge
while output_axis_tvalid:
yield clk.posedge
yield clk.posedge
stop_time = now()
trigger.next = 1
yield clk.posedge
trigger.next = 0
yield clk.posedge
while output_axis_tvalid:
yield clk.posedge
yield clk.posedge
yield clk.posedge
# discard first trigger output
if not sink_queue.empty():
rx_frame = sink_queue.get()
# check second trigger output
if not sink_queue.empty():
rx_frame = sink_queue.get()
rx_frame_values = struct.unpack(">HLLL", rx_frame.data)
cycles = (stop_time - start_time) / 8
print(rx_frame_values)
assert rx_frame_values[0] == 1
assert rx_frame_values[1] == cycles*8
assert rx_frame_values[2] == sum(len(f.data) for f in test_frame)
assert rx_frame_values[3] == len(test_frame)
yield delay(100)
yield clk.posedge
print("test 10: various length packets with intermediate trigger")
current_test.next = 10
yield clk.posedge
start_time = now()
trigger.next = 1
yield clk.posedge
trigger.next = 0
lens = [32, 48, 96, 128, 256]
test_frame = []
for i in range(len(lens)):
test_frame.append(axis_ep.AXIStreamFrame(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
bytearray(range(lens[i]))))
for f in test_frame:
source_queue.put(f)
yield clk.posedge
yield delay(200)
yield clk.posedge
trigger_time = now()
trigger.next = 1
yield clk.posedge
trigger.next = 0
yield clk.posedge
while monitor_axis_tvalid:
yield clk.posedge
while output_axis_tvalid:
yield clk.posedge
yield clk.posedge
stop_time = now()
trigger.next = 1
yield clk.posedge
trigger.next = 0
yield clk.posedge
while output_axis_tvalid:
yield clk.posedge
yield clk.posedge
yield clk.posedge
# discard first trigger output
if not sink_queue.empty():
rx_frame = sink_queue.get()
# check second trigger output
if not sink_queue.empty():
rx_frame = sink_queue.get()
# check second trigger output
if not sink_queue.empty():
rx_frame2 = sink_queue.get()
rx_frame_values = struct.unpack(">HLLL", rx_frame.data)
cycles = (stop_time - start_time) / 8
cycles1 = (trigger_time - start_time) / 8
print(rx_frame_values)
rx_frame2_values = struct.unpack(">HLLL", rx_frame2.data)
cycles2 = (stop_time - trigger_time) / 8
print(rx_frame2_values)
assert rx_frame_values[0] == 1
assert rx_frame2_values[0] == 1
assert rx_frame_values[1] == cycles1*8
assert rx_frame2_values[1] == cycles2*8
assert rx_frame_values[1] + rx_frame2_values[1] == cycles*8
assert rx_frame_values[2] + rx_frame2_values[2] == sum(len(f.data) for f in test_frame)
assert rx_frame_values[3] + rx_frame2_values[3] == len(test_frame)
yield delay(100)
raise StopSimulation
return dut, source, monitor_sink, sink, clkgen, check
def test_bench():
os.chdir(os.path.dirname(os.path.abspath(__file__)))
sim = Simulation(bench())
sim.run()
if __name__ == '__main__':
print("Running test...")
test_bench()

View File

@ -1,102 +0,0 @@
/*
Copyright (c) 2014 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
// Language: Verilog 2001
`timescale 1 ns / 1 ps
module test_axis_stat_counter;
// Inputs
reg clk = 0;
reg rst = 0;
reg [7:0] current_test = 0;
reg [63:0] monitor_axis_tdata = 8'd0;
reg [7:0] monitor_axis_tkeep = 8'd0;
reg monitor_axis_tvalid = 1'b0;
reg monitor_axis_tready = 1'b0;
reg monitor_axis_tlast = 1'b0;
reg monitor_axis_tuser = 1'b0;
reg output_axis_tready = 1'b0;
reg [15:0] tag = 0;
reg trigger = 0;
// Outputs
wire [7:0] output_axis_tdata;
wire output_axis_tvalid;
wire output_axis_tlast;
wire output_axis_tuser;
wire busy;
initial begin
// myhdl integration
$from_myhdl(clk,
rst,
current_test,
monitor_axis_tdata,
monitor_axis_tkeep,
monitor_axis_tvalid,
monitor_axis_tready,
monitor_axis_tlast,
monitor_axis_tuser,
output_axis_tready,
tag,
trigger);
$to_myhdl(output_axis_tdata,
output_axis_tvalid,
output_axis_tlast,
output_axis_tuser,
busy);
// dump file
$dumpfile("test_axis_stat_counter.lxt");
$dumpvars(0, test_axis_stat_counter);
end
axis_stat_counter #(
.DATA_WIDTH(64)
)
UUT (
.clk(clk),
.rst(rst),
// axi monitor input
.monitor_axis_tkeep(monitor_axis_tkeep),
.monitor_axis_tvalid(monitor_axis_tvalid),
.monitor_axis_tready(monitor_axis_tready),
.monitor_axis_tlast(monitor_axis_tlast),
// axi output
.output_axis_tdata(output_axis_tdata),
.output_axis_tvalid(output_axis_tvalid),
.output_axis_tready(output_axis_tready),
.output_axis_tlast(output_axis_tlast),
.output_axis_tuser(output_axis_tuser),
// configuration
.tag(tag),
.trigger(trigger),
// status
.busy(busy)
);
endmodule

View File

@ -1,231 +0,0 @@
#!/usr/bin/env python2
"""
Copyright (c) 2014 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""
from myhdl import *
import os
from Queue import Queue
import axis_ep
import ll_ep
module = 'll_axis_bridge'
srcs = []
srcs.append("../rtl/%s.v" % module)
srcs.append("test_%s.v" % module)
src = ' '.join(srcs)
build_cmd = "iverilog -o test_%s.vvp %s" % (module, src)
def dut_ll_axis_bridge(clk,
rst,
current_test,
ll_data_in,
ll_sof_in_n,
ll_eof_in_n,
ll_src_rdy_in_n,
ll_dst_rdy_out_n,
axis_tdata,
axis_tvalid,
axis_tready,
axis_tlast):
os.system(build_cmd)
return Cosimulation("vvp -m myhdl test_%s.vvp -lxt2" % module,
clk=clk,
rst=rst,
current_test=current_test,
ll_data_in=ll_data_in,
ll_sof_in_n=ll_sof_in_n,
ll_eof_in_n=ll_eof_in_n,
ll_src_rdy_in_n=ll_src_rdy_in_n,
ll_dst_rdy_out_n=ll_dst_rdy_out_n,
axis_tdata=axis_tdata,
axis_tvalid=axis_tvalid,
axis_tready=axis_tready,
axis_tlast=axis_tlast)
def bench():
# Inputs
clk = Signal(bool(0))
rst = Signal(bool(0))
current_test = Signal(intbv(0)[8:])
ll_data_in = Signal(intbv(0)[8:])
ll_sof_in_n = Signal(bool(1))
ll_eof_in_n = Signal(bool(1))
ll_src_rdy_in_n = Signal(bool(1))
axis_tready = Signal(bool(0))
# Outputs
axis_tdata = Signal(intbv(0)[8:])
axis_tvalid = Signal(bool(0))
axis_tlast = Signal(bool(0))
ll_dst_rdy_out_n = Signal(bool(1))
# sources and sinks
source_queue = Queue()
source_pause = Signal(bool(0))
sink_queue = Queue()
sink_pause = Signal(bool(0))
source = ll_ep.LocalLinkSource(clk,
rst,
data_out=ll_data_in,
sof_out_n=ll_sof_in_n,
eof_out_n=ll_eof_in_n,
src_rdy_out_n=ll_src_rdy_in_n,
dst_rdy_in_n=ll_dst_rdy_out_n,
fifo=source_queue,
pause=source_pause,
name='source')
sink = axis_ep.AXIStreamSink(clk,
rst,
tdata=axis_tdata,
tvalid=axis_tvalid,
tready=axis_tready,
tlast=axis_tlast,
fifo=sink_queue,
pause=sink_pause,
name='sink')
# DUT
dut = dut_ll_axis_bridge(clk,
rst,
current_test,
ll_data_in,
ll_sof_in_n,
ll_eof_in_n,
ll_src_rdy_in_n,
ll_dst_rdy_out_n,
axis_tdata,
axis_tvalid,
axis_tready,
axis_tlast)
@always(delay(4))
def clkgen():
clk.next = not clk
@instance
def check():
yield delay(100)
yield clk.posedge
rst.next = 1
yield clk.posedge
rst.next = 0
yield clk.posedge
yield delay(100)
yield clk.posedge
yield clk.posedge
yield clk.posedge
print("test 1: test packet")
current_test.next = 1
source_queue.put(bytearray(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10'))
yield clk.posedge
yield axis_tlast.negedge
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert bytearray(rx_frame) == (b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
yield delay(100)
yield clk.posedge
print("test 2: test packet with pauses")
current_test.next = 2
source_queue.put(bytearray(b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10'))
yield clk.posedge
yield delay(64)
yield clk.posedge
source_pause.next = True
yield delay(32)
yield clk.posedge
source_pause.next = False
yield delay(64)
yield clk.posedge
sink_pause.next = True
yield delay(32)
yield clk.posedge
sink_pause.next = False
yield axis_tlast.negedge
yield clk.posedge
yield clk.posedge
rx_frame = None
if not sink_queue.empty():
rx_frame = sink_queue.get()
assert bytearray(rx_frame) == (b'\xDA\xD1\xD2\xD3\xD4\xD5' +
b'\x5A\x51\x52\x53\x54\x55' +
b'\x80\x00' +
b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
yield delay(100)
raise StopSimulation
return dut, source, sink, clkgen, check
def test_bench():
os.chdir(os.path.dirname(os.path.abspath(__file__)))
sim = Simulation(bench())
sim.run()
if __name__ == '__main__':
print("Running test...")
test_bench()

View File

@ -1,85 +0,0 @@
/*
Copyright (c) 2014 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
// Language: Verilog 2001
`timescale 1 ns / 1 ps
module test_ll_axis_bridge;
// Inputs
reg clk = 0;
reg rst = 0;
reg [7:0] current_test = 0;
reg [7:0] ll_data_in = 0;
reg ll_sof_in_n = 1;
reg ll_eof_in_n = 1;
reg ll_src_rdy_in_n = 1;
reg axis_tready = 0;
// Outputs
wire ll_dst_rdy_out_n;
wire [7:0] axis_tdata;
wire axis_tvalid;
wire axis_tlast;
initial begin
// myhdl integration
$from_myhdl(clk,
rst,
current_test,
ll_data_in,
ll_sof_in_n,
ll_eof_in_n,
ll_src_rdy_in_n,
axis_tready);
$to_myhdl(axis_tdata,
axis_tvalid,
axis_tlast,
ll_dst_rdy_out_n);
// dump file
$dumpfile("test_ll_axis_bridge.lxt");
$dumpvars(0, test_ll_axis_bridge);
end
ll_axis_bridge
UUT (
.clk(clk),
.rst(rst),
// locallink input
.ll_data_in(ll_data_in),
.ll_sof_in_n(ll_sof_in_n),
.ll_eof_in_n(ll_eof_in_n),
.ll_src_rdy_in_n(ll_src_rdy_in_n),
.ll_dst_rdy_out_n(ll_dst_rdy_out_n),
// axi output
.axis_tdata(axis_tdata),
.axis_tvalid(axis_tvalid),
.axis_tready(axis_tready),
.axis_tlast(axis_tlast)
);
endmodule