mirror of
https://github.com/alexforencich/verilog-ethernet.git
synced 2025-01-14 06:43:18 +08:00
merged changes in axis
This commit is contained in:
commit
7775733120
@ -7,7 +7,7 @@ before_install:
|
|||||||
- export d=`pwd`
|
- export d=`pwd`
|
||||||
- sudo apt-get update -qq
|
- sudo apt-get update -qq
|
||||||
- sudo apt-get install -y iverilog
|
- sudo apt-get install -y iverilog
|
||||||
- hg clone https://bitbucket.org/jandecaluwe/myhdl
|
- hg clone https://bitbucket.org/alexforencich/myhdl
|
||||||
- cd $d/myhdl && sudo python setup.py install
|
- cd $d/myhdl && sudo python setup.py install
|
||||||
- cd $d/myhdl/cosimulation/icarus && make && sudo install -m 0755 -D ./myhdl.vpi /usr/lib/ivl/myhdl.vpi
|
- cd $d/myhdl/cosimulation/icarus && make && sudo install -m 0755 -D ./myhdl.vpi /usr/lib/ivl/myhdl.vpi
|
||||||
- cd $d
|
- cd $d
|
||||||
|
@ -154,6 +154,27 @@ Datapath register. Use to improve timing for long routes.
|
|||||||
|
|
||||||
Datapath register with tkeep signal. Use to improve timing for long routes.
|
Datapath register with tkeep signal. Use to improve timing for long routes.
|
||||||
|
|
||||||
|
### axis_srl_fifo module
|
||||||
|
|
||||||
|
SRL-based FIFO. Good for small FIFOs. SRLs on Xilinx FPGAs have a very fast
|
||||||
|
input setup time, so this module can be used to aid in timing closure.
|
||||||
|
|
||||||
|
### axis_srl_fifo_64 module
|
||||||
|
|
||||||
|
SRL-based FIFO with tkeep signal. Good for small FIFOs. SRLs on Xilinx FPGAs
|
||||||
|
have a very fast input setup time, so this module can be used to aid in timing
|
||||||
|
closure.
|
||||||
|
|
||||||
|
### axis_srl_register module
|
||||||
|
|
||||||
|
SRL-based register. SRLs on Xilinx FPGAs have a very fast input setup time,
|
||||||
|
so this module can be used to aid in timing closure.
|
||||||
|
|
||||||
|
### axis_srl_register_64 module
|
||||||
|
|
||||||
|
SRL-based register with tkeep signal. SRLs on Xilinx FPGAs have a very fast
|
||||||
|
input setup time, so this module can be used to aid in timing closure.
|
||||||
|
|
||||||
### axis_stat_counter module
|
### axis_stat_counter module
|
||||||
|
|
||||||
Statistics counter module. Counts bytes and frames passing through monitored
|
Statistics counter module. Counts bytes and frames passing through monitored
|
||||||
@ -213,6 +234,10 @@ Parametrizable priority encoder.
|
|||||||
rtl/axis_rate_limit_64.v : Fractional rate limiter (64 bit)
|
rtl/axis_rate_limit_64.v : Fractional rate limiter (64 bit)
|
||||||
rtl/axis_register.v : AXI Stream register
|
rtl/axis_register.v : AXI Stream register
|
||||||
rtl/axis_register_64.v : AXI Stream register (64 bit)
|
rtl/axis_register_64.v : AXI Stream register (64 bit)
|
||||||
|
rtl/axis_srl_fifo.v : SRL-based FIFO
|
||||||
|
rtl/axis_srl_fifo_64.v : SRL-based FIFO (64 bit)
|
||||||
|
rtl/axis_srl_register.v : SRL-based register
|
||||||
|
rtl/axis_srl_register_64.v : SRL-based register (64 bit)
|
||||||
rtl/axis_stat_counter.v : Statistics counter
|
rtl/axis_stat_counter.v : Statistics counter
|
||||||
rtl/ll_axis_bridge.v : LocalLink to AXI stream bridge
|
rtl/ll_axis_bridge.v : LocalLink to AXI stream bridge
|
||||||
rtl/priority_encoder.v : Parametrizable priority encoder
|
rtl/priority_encoder.v : Parametrizable priority encoder
|
||||||
|
140
lib/axis/rtl/axis_srl_fifo.v
Normal file
140
lib/axis/rtl/axis_srl_fifo.v
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
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 SRL-based FIFO
|
||||||
|
*/
|
||||||
|
module axis_srl_fifo #
|
||||||
|
(
|
||||||
|
parameter DATA_WIDTH = 8,
|
||||||
|
parameter DEPTH = 16
|
||||||
|
)
|
||||||
|
(
|
||||||
|
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,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Status
|
||||||
|
*/
|
||||||
|
output wire [$clog2(DEPTH+1)-1:0] count
|
||||||
|
);
|
||||||
|
|
||||||
|
reg [DATA_WIDTH+2-1:0] data_reg[DEPTH-1:0];
|
||||||
|
reg [$clog2(DEPTH+1)-1:0] ptr_reg = 0, ptr_next;
|
||||||
|
reg full_reg = 0, full_next;
|
||||||
|
reg empty_reg = 1, empty_next;
|
||||||
|
|
||||||
|
assign {output_axis_tlast, output_axis_tuser, output_axis_tdata} = data_reg[ptr_reg-1];
|
||||||
|
assign input_axis_tready = ~full_reg;
|
||||||
|
assign output_axis_tvalid = ~empty_reg;
|
||||||
|
assign count = ptr_reg;
|
||||||
|
|
||||||
|
wire ptr_empty = ptr_reg == 0;
|
||||||
|
wire ptr_empty1 = ptr_reg == 1;
|
||||||
|
wire ptr_full = ptr_reg == DEPTH;
|
||||||
|
wire ptr_full1 = ptr_reg == DEPTH-1;
|
||||||
|
|
||||||
|
reg shift;
|
||||||
|
reg inc;
|
||||||
|
reg dec;
|
||||||
|
|
||||||
|
integer i;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
for (i = 0; i < DEPTH; i = i + 1) begin
|
||||||
|
data_reg[i] <= 0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @* begin
|
||||||
|
shift = 0;
|
||||||
|
inc = 0;
|
||||||
|
dec = 0;
|
||||||
|
ptr_next = ptr_reg;
|
||||||
|
full_next = full_reg;
|
||||||
|
empty_next = empty_reg;
|
||||||
|
|
||||||
|
if (output_axis_tready & input_axis_tvalid & ~full_reg) begin
|
||||||
|
shift = 1;
|
||||||
|
inc = ptr_empty;
|
||||||
|
empty_next = 0;
|
||||||
|
end else if (output_axis_tready & output_axis_tvalid) begin
|
||||||
|
dec = 1;
|
||||||
|
full_next = 0;
|
||||||
|
empty_next = ptr_empty1;
|
||||||
|
end else if (input_axis_tvalid & input_axis_tready) begin
|
||||||
|
shift = 1;
|
||||||
|
inc = 1;
|
||||||
|
full_next = ptr_full1;
|
||||||
|
empty_next = 0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge clk) begin
|
||||||
|
if (rst) begin
|
||||||
|
ptr_reg <= 0;
|
||||||
|
end else begin
|
||||||
|
if (shift) begin
|
||||||
|
data_reg[0] <= {input_axis_tlast, input_axis_tuser, input_axis_tdata};
|
||||||
|
for (i = 0; i < DEPTH-1; i = i + 1) begin
|
||||||
|
data_reg[i+1] <= data_reg[i];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if (inc) begin
|
||||||
|
ptr_reg <= ptr_reg + 1;
|
||||||
|
end else if (dec) begin
|
||||||
|
ptr_reg <= ptr_reg - 1;
|
||||||
|
end else begin
|
||||||
|
ptr_reg <= ptr_reg;
|
||||||
|
end
|
||||||
|
|
||||||
|
full_reg <= full_next;
|
||||||
|
empty_reg <= empty_next;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
143
lib/axis/rtl/axis_srl_fifo_64.v
Normal file
143
lib/axis/rtl/axis_srl_fifo_64.v
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
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 SRL-based FIFO (64 bit datapath)
|
||||||
|
*/
|
||||||
|
module axis_srl_fifo_64 #
|
||||||
|
(
|
||||||
|
parameter DATA_WIDTH = 64,
|
||||||
|
parameter KEEP_WIDTH = (DATA_WIDTH/8),
|
||||||
|
parameter DEPTH = 16
|
||||||
|
)
|
||||||
|
(
|
||||||
|
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,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Status
|
||||||
|
*/
|
||||||
|
output wire [$clog2(DEPTH+1)-1:0] count
|
||||||
|
);
|
||||||
|
|
||||||
|
reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] data_reg[DEPTH-1:0];
|
||||||
|
reg [$clog2(DEPTH+1)-1:0] ptr_reg = 0, ptr_next;
|
||||||
|
reg full_reg = 0, full_next;
|
||||||
|
reg empty_reg = 1, empty_next;
|
||||||
|
|
||||||
|
assign {output_axis_tlast, output_axis_tuser, output_axis_tkeep, output_axis_tdata} = data_reg[ptr_reg-1];
|
||||||
|
assign input_axis_tready = ~full_reg;
|
||||||
|
assign output_axis_tvalid = ~empty_reg;
|
||||||
|
assign count = ptr_reg;
|
||||||
|
|
||||||
|
wire ptr_empty = ptr_reg == 0;
|
||||||
|
wire ptr_empty1 = ptr_reg == 1;
|
||||||
|
wire ptr_full = ptr_reg == DEPTH;
|
||||||
|
wire ptr_full1 = ptr_reg == DEPTH-1;
|
||||||
|
|
||||||
|
reg shift;
|
||||||
|
reg inc;
|
||||||
|
reg dec;
|
||||||
|
|
||||||
|
integer i;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
for (i = 0; i < DEPTH; i = i + 1) begin
|
||||||
|
data_reg[i] <= 0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @* begin
|
||||||
|
shift = 0;
|
||||||
|
inc = 0;
|
||||||
|
dec = 0;
|
||||||
|
ptr_next = ptr_reg;
|
||||||
|
full_next = full_reg;
|
||||||
|
empty_next = empty_reg;
|
||||||
|
|
||||||
|
if (output_axis_tready & input_axis_tvalid & ~full_reg) begin
|
||||||
|
shift = 1;
|
||||||
|
inc = ptr_empty;
|
||||||
|
empty_next = 0;
|
||||||
|
end else if (output_axis_tready & output_axis_tvalid) begin
|
||||||
|
dec = 1;
|
||||||
|
full_next = 0;
|
||||||
|
empty_next = ptr_empty1;
|
||||||
|
end else if (input_axis_tvalid & input_axis_tready) begin
|
||||||
|
shift = 1;
|
||||||
|
inc = 1;
|
||||||
|
full_next = ptr_full1;
|
||||||
|
empty_next = 0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge clk) begin
|
||||||
|
if (rst) begin
|
||||||
|
ptr_reg <= 0;
|
||||||
|
end else begin
|
||||||
|
if (shift) begin
|
||||||
|
data_reg[0] <= {input_axis_tlast, input_axis_tuser, input_axis_tkeep, input_axis_tdata};
|
||||||
|
for (i = 0; i < DEPTH-1; i = i + 1) begin
|
||||||
|
data_reg[i+1] <= data_reg[i];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if (inc) begin
|
||||||
|
ptr_reg <= ptr_reg + 1;
|
||||||
|
end else if (dec) begin
|
||||||
|
ptr_reg <= ptr_reg - 1;
|
||||||
|
end else begin
|
||||||
|
ptr_reg <= ptr_reg;
|
||||||
|
end
|
||||||
|
|
||||||
|
full_reg <= full_next;
|
||||||
|
empty_reg <= empty_next;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
101
lib/axis/rtl/axis_srl_register.v
Normal file
101
lib/axis/rtl/axis_srl_register.v
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
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 SRL-based FIFO register
|
||||||
|
*/
|
||||||
|
module axis_srl_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
|
||||||
|
);
|
||||||
|
|
||||||
|
reg [DATA_WIDTH+2-1:0] data_reg[1:0];
|
||||||
|
reg valid_reg[1:0];
|
||||||
|
reg ptr_reg = 0;
|
||||||
|
reg full_reg = 0;
|
||||||
|
|
||||||
|
assign {output_axis_tlast, output_axis_tuser, output_axis_tdata} = data_reg[ptr_reg];
|
||||||
|
assign input_axis_tready = ~full_reg;
|
||||||
|
assign output_axis_tvalid = valid_reg[ptr_reg];
|
||||||
|
|
||||||
|
integer i;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
for (i = 0; i < 2; i = i + 1) begin
|
||||||
|
data_reg[i] <= 0;
|
||||||
|
valid_reg[i] <= 0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge clk) begin
|
||||||
|
if (rst) begin
|
||||||
|
ptr_reg <= 0;
|
||||||
|
end else begin
|
||||||
|
// transfer empty to full
|
||||||
|
full_reg <= ~output_axis_tready & output_axis_tvalid;
|
||||||
|
|
||||||
|
// transfer in if not full
|
||||||
|
if (input_axis_tready) begin
|
||||||
|
data_reg[0] <= {input_axis_tlast, input_axis_tuser, input_axis_tdata};
|
||||||
|
valid_reg[0] <= input_axis_tvalid;
|
||||||
|
for (i = 0; i < 1; i = i + 1) begin
|
||||||
|
data_reg[i+1] <= data_reg[i];
|
||||||
|
valid_reg[i+1] <= valid_reg[i];
|
||||||
|
end
|
||||||
|
ptr_reg <= valid_reg[0];
|
||||||
|
end
|
||||||
|
|
||||||
|
if (output_axis_tready) begin
|
||||||
|
ptr_reg <= 0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
104
lib/axis/rtl/axis_srl_register_64.v
Normal file
104
lib/axis/rtl/axis_srl_register_64.v
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
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 SRL-based FIFO register (64 bit datapath)
|
||||||
|
*/
|
||||||
|
module axis_srl_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
|
||||||
|
);
|
||||||
|
|
||||||
|
reg [DATA_WIDTH+KEEP_WIDTH+2-1:0] data_reg[1:0];
|
||||||
|
reg valid_reg[1:0];
|
||||||
|
reg ptr_reg = 0;
|
||||||
|
reg full_reg = 0;
|
||||||
|
|
||||||
|
assign {output_axis_tlast, output_axis_tuser, output_axis_tkeep, output_axis_tdata} = data_reg[ptr_reg];
|
||||||
|
assign input_axis_tready = ~full_reg;
|
||||||
|
assign output_axis_tvalid = valid_reg[ptr_reg];
|
||||||
|
|
||||||
|
integer i;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
for (i = 0; i < 2; i = i + 1) begin
|
||||||
|
data_reg[i] <= 0;
|
||||||
|
valid_reg[i] <= 0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge clk) begin
|
||||||
|
if (rst) begin
|
||||||
|
ptr_reg <= 0;
|
||||||
|
end else begin
|
||||||
|
// transfer empty to full
|
||||||
|
full_reg <= ~output_axis_tready & output_axis_tvalid;
|
||||||
|
|
||||||
|
// transfer in if not full
|
||||||
|
if (input_axis_tready) begin
|
||||||
|
data_reg[0] <= {input_axis_tlast, input_axis_tuser, input_axis_tkeep, input_axis_tdata};
|
||||||
|
valid_reg[0] <= input_axis_tvalid;
|
||||||
|
for (i = 0; i < 1; i = i + 1) begin
|
||||||
|
data_reg[i+1] <= data_reg[i];
|
||||||
|
valid_reg[i+1] <= valid_reg[i];
|
||||||
|
end
|
||||||
|
ptr_reg <= valid_reg[0];
|
||||||
|
end
|
||||||
|
|
||||||
|
if (output_axis_tready) begin
|
||||||
|
ptr_reg <= 0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
404
lib/axis/tb/test_axis_srl_fifo.py
Executable file
404
lib/axis/tb/test_axis_srl_fifo.py
Executable file
@ -0,0 +1,404 @@
|
|||||||
|
#!/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_srl_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_srl_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,
|
||||||
|
|
||||||
|
count):
|
||||||
|
|
||||||
|
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,
|
||||||
|
|
||||||
|
count=count)
|
||||||
|
|
||||||
|
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))
|
||||||
|
|
||||||
|
count = Signal(intbv(0)[3:])
|
||||||
|
|
||||||
|
# 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_srl_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,
|
||||||
|
|
||||||
|
count)
|
||||||
|
|
||||||
|
@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('\xDA\xD1\xD2\xD3\xD4\xD5' +
|
||||||
|
'\x5A\x51\x52\x53\x54\x55' +
|
||||||
|
'\x80\x00' +
|
||||||
|
'\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('\xDA\xD1\xD2\xD3\xD4\xD5' +
|
||||||
|
'\x5A\x51\x52\x53\x54\x55' +
|
||||||
|
'\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('\xDA\xD1\xD2\xD3\xD4\xD5' +
|
||||||
|
'\x5A\x51\x52\x53\x54\x55' +
|
||||||
|
'\x80\x00' +
|
||||||
|
'\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('\xDA\xD1\xD2\xD3\xD4\xD5' +
|
||||||
|
'\x5A\x51\x52\x53\x54\x55' +
|
||||||
|
'\x80\x00' +
|
||||||
|
'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
|
||||||
|
test_frame2 = axis_ep.AXIStreamFrame('\xDA\xD1\xD2\xD3\xD4\xD5' +
|
||||||
|
'\x5A\x51\x52\x53\x54\x55' +
|
||||||
|
'\x80\x00' +
|
||||||
|
'\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('\xDA\xD1\xD2\xD3\xD4\xD5' +
|
||||||
|
'\x5A\x51\x52\x53\x54\x55' +
|
||||||
|
'\x80\x00' +
|
||||||
|
'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
|
||||||
|
test_frame2 = axis_ep.AXIStreamFrame('\xDA\xD1\xD2\xD3\xD4\xD5' +
|
||||||
|
'\x5A\x51\x52\x53\x54\x55' +
|
||||||
|
'\x80\x00' +
|
||||||
|
'\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('\xDA\xD1\xD2\xD3\xD4\xD5' +
|
||||||
|
'\x5A\x51\x52\x53\x54\x55' +
|
||||||
|
'\x80\x00' +
|
||||||
|
'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
|
||||||
|
test_frame2 = axis_ep.AXIStreamFrame('\xDA\xD1\xD2\xD3\xD4\xD5' +
|
||||||
|
'\x5A\x51\x52\x53\x54\x55' +
|
||||||
|
'\x80\x00' +
|
||||||
|
'\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('\xDA\xD1\xD2\xD3\xD4\xD5' +
|
||||||
|
'\x5A\x51\x52\x53\x54\x55' +
|
||||||
|
'\x80\x00' +
|
||||||
|
'\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()
|
||||||
|
|
96
lib/axis/tb/test_axis_srl_fifo.v
Normal file
96
lib/axis/tb/test_axis_srl_fifo.v
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
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_srl_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;
|
||||||
|
|
||||||
|
wire [2:0] count;
|
||||||
|
|
||||||
|
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,
|
||||||
|
count);
|
||||||
|
|
||||||
|
// dump file
|
||||||
|
$dumpfile("test_axis_srl_fifo.lxt");
|
||||||
|
$dumpvars(0, test_axis_srl_fifo);
|
||||||
|
end
|
||||||
|
|
||||||
|
axis_srl_fifo #(
|
||||||
|
.DEPTH(4),
|
||||||
|
.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),
|
||||||
|
// Status
|
||||||
|
.count(count)
|
||||||
|
);
|
||||||
|
|
||||||
|
endmodule
|
414
lib/axis/tb/test_axis_srl_fifo_64.py
Executable file
414
lib/axis/tb/test_axis_srl_fifo_64.py
Executable file
@ -0,0 +1,414 @@
|
|||||||
|
#!/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_srl_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_srl_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,
|
||||||
|
|
||||||
|
count):
|
||||||
|
|
||||||
|
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,
|
||||||
|
|
||||||
|
count=count)
|
||||||
|
|
||||||
|
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))
|
||||||
|
|
||||||
|
count = Signal(intbv(0)[3:])
|
||||||
|
|
||||||
|
# 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_srl_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,
|
||||||
|
|
||||||
|
count)
|
||||||
|
|
||||||
|
@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('\xDA\xD1\xD2\xD3\xD4\xD5' +
|
||||||
|
'\x5A\x51\x52\x53\x54\x55' +
|
||||||
|
'\x80\x00' +
|
||||||
|
'\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('\xDA\xD1\xD2\xD3\xD4\xD5' +
|
||||||
|
'\x5A\x51\x52\x53\x54\x55' +
|
||||||
|
'\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('\xDA\xD1\xD2\xD3\xD4\xD5' +
|
||||||
|
'\x5A\x51\x52\x53\x54\x55' +
|
||||||
|
'\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('\xDA\xD1\xD2\xD3\xD4\xD5' +
|
||||||
|
'\x5A\x51\x52\x53\x54\x55' +
|
||||||
|
'\x80\x00' +
|
||||||
|
'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
|
||||||
|
test_frame2 = axis_ep.AXIStreamFrame('\xDA\xD1\xD2\xD3\xD4\xD5' +
|
||||||
|
'\x5A\x51\x52\x53\x54\x55' +
|
||||||
|
'\x80\x00' +
|
||||||
|
'\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('\xDA\xD1\xD2\xD3\xD4\xD5' +
|
||||||
|
'\x5A\x51\x52\x53\x54\x55' +
|
||||||
|
'\x80\x00' +
|
||||||
|
'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
|
||||||
|
test_frame2 = axis_ep.AXIStreamFrame('\xDA\xD1\xD2\xD3\xD4\xD5' +
|
||||||
|
'\x5A\x51\x52\x53\x54\x55' +
|
||||||
|
'\x80\x00' +
|
||||||
|
'\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('\xDA\xD1\xD2\xD3\xD4\xD5' +
|
||||||
|
'\x5A\x51\x52\x53\x54\x55' +
|
||||||
|
'\x80\x00' +
|
||||||
|
'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
|
||||||
|
test_frame2 = axis_ep.AXIStreamFrame('\xDA\xD1\xD2\xD3\xD4\xD5' +
|
||||||
|
'\x5A\x51\x52\x53\x54\x55' +
|
||||||
|
'\x80\x00' +
|
||||||
|
'\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('\xDA\xD1\xD2\xD3\xD4\xD5' +
|
||||||
|
'\x5A\x51\x52\x53\x54\x55' +
|
||||||
|
'\x80\x00' +
|
||||||
|
'\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()
|
||||||
|
|
102
lib/axis/tb/test_axis_srl_fifo_64.v
Normal file
102
lib/axis/tb/test_axis_srl_fifo_64.v
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
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_srl_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;
|
||||||
|
|
||||||
|
wire [2:0] count;
|
||||||
|
|
||||||
|
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,
|
||||||
|
count);
|
||||||
|
|
||||||
|
// dump file
|
||||||
|
$dumpfile("test_axis_srl_fifo_64.lxt");
|
||||||
|
$dumpvars(0, test_axis_srl_fifo_64);
|
||||||
|
end
|
||||||
|
|
||||||
|
axis_srl_fifo_64 #(
|
||||||
|
.DEPTH(4),
|
||||||
|
.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),
|
||||||
|
// Status
|
||||||
|
.count(count)
|
||||||
|
);
|
||||||
|
|
||||||
|
endmodule
|
396
lib/axis/tb/test_axis_srl_register.py
Executable file
396
lib/axis/tb/test_axis_srl_register.py
Executable file
@ -0,0 +1,396 @@
|
|||||||
|
#!/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_srl_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_srl_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_srl_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('\xDA\xD1\xD2\xD3\xD4\xD5' +
|
||||||
|
'\x5A\x51\x52\x53\x54\x55' +
|
||||||
|
'\x80\x00' +
|
||||||
|
'\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('\xDA\xD1\xD2\xD3\xD4\xD5' +
|
||||||
|
'\x5A\x51\x52\x53\x54\x55' +
|
||||||
|
'\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('\xDA\xD1\xD2\xD3\xD4\xD5' +
|
||||||
|
'\x5A\x51\x52\x53\x54\x55' +
|
||||||
|
'\x80\x00' +
|
||||||
|
'\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('\xDA\xD1\xD2\xD3\xD4\xD5' +
|
||||||
|
'\x5A\x51\x52\x53\x54\x55' +
|
||||||
|
'\x80\x00' +
|
||||||
|
'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
|
||||||
|
test_frame2 = axis_ep.AXIStreamFrame('\xDA\xD1\xD2\xD3\xD4\xD5' +
|
||||||
|
'\x5A\x51\x52\x53\x54\x55' +
|
||||||
|
'\x80\x00' +
|
||||||
|
'\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('\xDA\xD1\xD2\xD3\xD4\xD5' +
|
||||||
|
'\x5A\x51\x52\x53\x54\x55' +
|
||||||
|
'\x80\x00' +
|
||||||
|
'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
|
||||||
|
test_frame2 = axis_ep.AXIStreamFrame('\xDA\xD1\xD2\xD3\xD4\xD5' +
|
||||||
|
'\x5A\x51\x52\x53\x54\x55' +
|
||||||
|
'\x80\x00' +
|
||||||
|
'\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('\xDA\xD1\xD2\xD3\xD4\xD5' +
|
||||||
|
'\x5A\x51\x52\x53\x54\x55' +
|
||||||
|
'\x80\x00' +
|
||||||
|
'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
|
||||||
|
test_frame2 = axis_ep.AXIStreamFrame('\xDA\xD1\xD2\xD3\xD4\xD5' +
|
||||||
|
'\x5A\x51\x52\x53\x54\x55' +
|
||||||
|
'\x80\x00' +
|
||||||
|
'\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('\xDA\xD1\xD2\xD3\xD4\xD5' +
|
||||||
|
'\x5A\x51\x52\x53\x54\x55' +
|
||||||
|
'\x80\x00' +
|
||||||
|
'\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()
|
||||||
|
|
90
lib/axis/tb/test_axis_srl_register.v
Normal file
90
lib/axis/tb/test_axis_srl_register.v
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
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_srl_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_srl_register.lxt");
|
||||||
|
$dumpvars(0, test_axis_srl_register);
|
||||||
|
end
|
||||||
|
|
||||||
|
axis_srl_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
|
406
lib/axis/tb/test_axis_srl_register_64.py
Executable file
406
lib/axis/tb/test_axis_srl_register_64.py
Executable file
@ -0,0 +1,406 @@
|
|||||||
|
#!/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_srl_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_srl_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_srl_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('\xDA\xD1\xD2\xD3\xD4\xD5' +
|
||||||
|
'\x5A\x51\x52\x53\x54\x55' +
|
||||||
|
'\x80\x00' +
|
||||||
|
'\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('\xDA\xD1\xD2\xD3\xD4\xD5' +
|
||||||
|
'\x5A\x51\x52\x53\x54\x55' +
|
||||||
|
'\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('\xDA\xD1\xD2\xD3\xD4\xD5' +
|
||||||
|
'\x5A\x51\x52\x53\x54\x55' +
|
||||||
|
'\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('\xDA\xD1\xD2\xD3\xD4\xD5' +
|
||||||
|
'\x5A\x51\x52\x53\x54\x55' +
|
||||||
|
'\x80\x00' +
|
||||||
|
'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
|
||||||
|
test_frame2 = axis_ep.AXIStreamFrame('\xDA\xD1\xD2\xD3\xD4\xD5' +
|
||||||
|
'\x5A\x51\x52\x53\x54\x55' +
|
||||||
|
'\x80\x00' +
|
||||||
|
'\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('\xDA\xD1\xD2\xD3\xD4\xD5' +
|
||||||
|
'\x5A\x51\x52\x53\x54\x55' +
|
||||||
|
'\x80\x00' +
|
||||||
|
'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
|
||||||
|
test_frame2 = axis_ep.AXIStreamFrame('\xDA\xD1\xD2\xD3\xD4\xD5' +
|
||||||
|
'\x5A\x51\x52\x53\x54\x55' +
|
||||||
|
'\x80\x00' +
|
||||||
|
'\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('\xDA\xD1\xD2\xD3\xD4\xD5' +
|
||||||
|
'\x5A\x51\x52\x53\x54\x55' +
|
||||||
|
'\x80\x00' +
|
||||||
|
'\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10')
|
||||||
|
test_frame2 = axis_ep.AXIStreamFrame('\xDA\xD1\xD2\xD3\xD4\xD5' +
|
||||||
|
'\x5A\x51\x52\x53\x54\x55' +
|
||||||
|
'\x80\x00' +
|
||||||
|
'\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('\xDA\xD1\xD2\xD3\xD4\xD5' +
|
||||||
|
'\x5A\x51\x52\x53\x54\x55' +
|
||||||
|
'\x80\x00' +
|
||||||
|
'\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()
|
||||||
|
|
96
lib/axis/tb/test_axis_srl_register_64.v
Normal file
96
lib/axis/tb/test_axis_srl_register_64.v
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
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_srl_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_srl_register_64.lxt");
|
||||||
|
$dumpvars(0, test_axis_srl_register_64);
|
||||||
|
end
|
||||||
|
|
||||||
|
axis_srl_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
|
Loading…
x
Reference in New Issue
Block a user