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

Add LocalLink to AXI stream bridge

This commit is contained in:
Alex Forencich 2014-09-13 21:23:11 -07:00
parent 74fa967071
commit e1955a29da
7 changed files with 899 additions and 0 deletions

79
rtl/axis_ll_bridge.v Normal file
View File

@ -0,0 +1,79 @@
/*
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

64
rtl/ll_axis_bridge.v Normal file
View File

@ -0,0 +1,64 @@
/*
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

123
tb/ll_ep.py Normal file
View File

@ -0,0 +1,123 @@
"""
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 *
def LocalLinkSource(clk, rst,
data_out,
sof_out_n,
eof_out_n,
src_rdy_out_n,
dst_rdy_in_n,
fifo,
pause=0,
name=None):
src_rdy_out_n_int = Signal(bool(True))
dst_rdy_in_n_int = Signal(bool(True))
@always_comb
def pause_logic():
dst_rdy_in_n_int.next = dst_rdy_in_n or pause
src_rdy_out_n.next = src_rdy_out_n_int or pause
@instance
def logic():
frame = []
while True:
yield clk.posedge, rst.posedge
if rst:
data_out.next = 0
src_rdy_out_n_int.next = True
sof_out_n.next = True
eof_out_n.next = True
else:
if not dst_rdy_in_n_int and not src_rdy_out_n:
if len(frame) > 0:
data_out.next = frame.pop(0)
src_rdy_out_n_int.next = False
sof_out_n.next = True
eof_out_n.next = len(frame) != 0
else:
src_rdy_out_n_int.next = True
eof_out_n.next = True
if (not eof_out_n and not dst_rdy_in_n_int and not src_rdy_out_n) or src_rdy_out_n_int:
if not fifo.empty():
frame = fifo.get()
if name is not None:
print("[%s] Sending frame %s" % (name, repr(frame)))
data_out.next = frame.pop(0)
src_rdy_out_n_int.next = False
sof_out_n.next = False
eof_out_n.next = len(frame) != 0
return logic, pause_logic
def LocalLinkSink(clk, rst,
data_in,
sof_in_n,
eof_in_n,
src_rdy_in_n,
dst_rdy_out_n,
fifo=None,
pause=0,
name=None):
src_rdy_in_n_int = Signal(bool(True))
dst_rdy_out_n_int = Signal(bool(True))
@always_comb
def pause_logic():
dst_rdy_out_n.next = dst_rdy_out_n_int or pause
src_rdy_in_n_int.next = src_rdy_in_n or pause
@instance
def logic():
frame = []
while True:
yield clk.posedge, rst.posedge
if rst:
dst_rdy_out_n_int.next = True
frame = []
else:
dst_rdy_out_n_int.next = False
if not src_rdy_in_n_int:
if not sof_in_n:
frame = []
frame.append(int(data_in))
if not eof_in_n:
if fifo is not None:
fifo.put(frame)
if name is not None:
print("[%s] Got frame %s" % (name, repr(frame)))
frame = []
return logic, pause_logic

232
tb/test_axis_ll_bridge.py Executable file
View File

@ -0,0 +1,232 @@
#!/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()

85
tb/test_axis_ll_bridge.v Normal file
View File

@ -0,0 +1,85 @@
/*
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

231
tb/test_ll_axis_bridge.py Executable file
View File

@ -0,0 +1,231 @@
#!/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()

85
tb/test_ll_axis_bridge.v Normal file
View File

@ -0,0 +1,85 @@
/*
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