mirror of
https://github.com/corundum/corundum.git
synced 2025-01-30 08:32:52 +08:00
Add RX checksum module and testbench
This commit is contained in:
parent
755c7959be
commit
6100e3ad78
198
fpga/common/rtl/rx_checksum.v
Normal file
198
fpga/common/rtl/rx_checksum.v
Normal file
@ -0,0 +1,198 @@
|
||||
/*
|
||||
|
||||
Copyright 2019, The Regents of the University of California.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''AS
|
||||
IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
OF SUCH DAMAGE.
|
||||
|
||||
The views and conclusions contained in the software and documentation are those
|
||||
of the authors and should not be interpreted as representing official policies,
|
||||
either expressed or implied, of The Regents of the University of California.
|
||||
|
||||
*/
|
||||
|
||||
// Language: Verilog 2001
|
||||
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
/*
|
||||
* Receive checksum offload module
|
||||
*/
|
||||
module rx_checksum #
|
||||
(
|
||||
parameter DATA_WIDTH = 256,
|
||||
parameter KEEP_WIDTH = (DATA_WIDTH/8)
|
||||
)
|
||||
(
|
||||
input wire clk,
|
||||
input wire rst,
|
||||
|
||||
/*
|
||||
* AXI input
|
||||
*/
|
||||
input wire [DATA_WIDTH-1:0] s_axis_tdata,
|
||||
input wire [KEEP_WIDTH-1:0] s_axis_tkeep,
|
||||
input wire s_axis_tvalid,
|
||||
input wire s_axis_tlast,
|
||||
|
||||
/*
|
||||
* Checksum output
|
||||
*/
|
||||
output wire [15:0] m_axis_csum,
|
||||
output wire m_axis_csum_valid
|
||||
);
|
||||
|
||||
// bus width assertions
|
||||
initial begin
|
||||
if (DATA_WIDTH != 256) begin
|
||||
$error("Error: AXI stream interface width must be 256");
|
||||
$finish;
|
||||
end
|
||||
|
||||
if (KEEP_WIDTH * 8 != DATA_WIDTH) begin
|
||||
$error("Error: AXI stream interface requires byte (8-bit) granularity");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
|
||||
reg [KEEP_WIDTH-1:0] mask_reg = 32'hffffc000;
|
||||
reg [DATA_WIDTH-1:0] s_axis_tdata_masked;
|
||||
|
||||
reg [16:0] sum_1_1_reg = 0;
|
||||
reg [16:0] sum_1_2_reg = 0;
|
||||
reg [16:0] sum_1_3_reg = 0;
|
||||
reg [16:0] sum_1_4_reg = 0;
|
||||
reg [16:0] sum_1_5_reg = 0;
|
||||
reg [16:0] sum_1_6_reg = 0;
|
||||
reg [16:0] sum_1_7_reg = 0;
|
||||
reg [16:0] sum_1_8_reg = 0;
|
||||
reg sum_1_valid_reg = 1'b0;
|
||||
reg sum_1_last_reg = 1'b0;
|
||||
|
||||
reg [17:0] sum_2_1_reg = 0;
|
||||
reg [17:0] sum_2_2_reg = 0;
|
||||
reg [17:0] sum_2_3_reg = 0;
|
||||
reg [17:0] sum_2_4_reg = 0;
|
||||
reg sum_2_valid_reg = 1'b0;
|
||||
reg sum_2_last_reg = 1'b0;
|
||||
|
||||
reg [18:0] sum_3_1_reg = 0;
|
||||
reg [18:0] sum_3_2_reg = 0;
|
||||
reg sum_3_valid_reg = 1'b0;
|
||||
reg sum_3_last_reg = 1'b0;
|
||||
|
||||
reg [19:0] sum_4_reg = 0;
|
||||
reg sum_4_valid_reg = 1'b0;
|
||||
reg sum_4_last_reg = 1'b0;
|
||||
|
||||
reg [20:0] sum_5_temp = 0;
|
||||
reg [15:0] sum_5_reg = 0;
|
||||
|
||||
reg [15:0] m_axis_csum_reg = 0;
|
||||
reg m_axis_csum_valid_reg = 1'b0;
|
||||
|
||||
assign m_axis_csum = m_axis_csum_reg;
|
||||
assign m_axis_csum_valid = m_axis_csum_valid_reg;
|
||||
|
||||
// Mask input data
|
||||
integer j;
|
||||
|
||||
always @* begin
|
||||
for (j = 0; j < KEEP_WIDTH; j = j + 1) begin
|
||||
s_axis_tdata_masked[j*8 +: 8] = (s_axis_tkeep[j] && mask_reg[j]) ? s_axis_tdata[j*8 +: 8] : 8'd0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
sum_1_valid_reg <= 1'b0;
|
||||
sum_2_valid_reg <= 1'b0;
|
||||
sum_3_valid_reg <= 1'b0;
|
||||
sum_4_valid_reg <= 1'b0;
|
||||
m_axis_csum_valid_reg <= 1'b0;
|
||||
|
||||
if (s_axis_tvalid) begin
|
||||
sum_1_1_reg <= {s_axis_tdata_masked[ 0*8 +: 8], s_axis_tdata_masked[ 1*8 +: 8]} + {s_axis_tdata_masked[ 2*8 +: 8], s_axis_tdata_masked[ 3*8 +: 8]};
|
||||
sum_1_2_reg <= {s_axis_tdata_masked[ 4*8 +: 8], s_axis_tdata_masked[ 5*8 +: 8]} + {s_axis_tdata_masked[ 6*8 +: 8], s_axis_tdata_masked[ 7*8 +: 8]};
|
||||
sum_1_3_reg <= {s_axis_tdata_masked[ 8*8 +: 8], s_axis_tdata_masked[ 9*8 +: 8]} + {s_axis_tdata_masked[10*8 +: 8], s_axis_tdata_masked[11*8 +: 8]};
|
||||
sum_1_4_reg <= {s_axis_tdata_masked[12*8 +: 8], s_axis_tdata_masked[13*8 +: 8]} + {s_axis_tdata_masked[14*8 +: 8], s_axis_tdata_masked[15*8 +: 8]};
|
||||
sum_1_5_reg <= {s_axis_tdata_masked[16*8 +: 8], s_axis_tdata_masked[17*8 +: 8]} + {s_axis_tdata_masked[18*8 +: 8], s_axis_tdata_masked[19*8 +: 8]};
|
||||
sum_1_6_reg <= {s_axis_tdata_masked[20*8 +: 8], s_axis_tdata_masked[21*8 +: 8]} + {s_axis_tdata_masked[22*8 +: 8], s_axis_tdata_masked[23*8 +: 8]};
|
||||
sum_1_7_reg <= {s_axis_tdata_masked[24*8 +: 8], s_axis_tdata_masked[25*8 +: 8]} + {s_axis_tdata_masked[26*8 +: 8], s_axis_tdata_masked[27*8 +: 8]};
|
||||
sum_1_8_reg <= {s_axis_tdata_masked[28*8 +: 8], s_axis_tdata_masked[29*8 +: 8]} + {s_axis_tdata_masked[30*8 +: 8], s_axis_tdata_masked[31*8 +: 8]};
|
||||
sum_1_valid_reg <= 1'b1;
|
||||
sum_1_last_reg <= s_axis_tlast;
|
||||
|
||||
if (s_axis_tlast) begin
|
||||
mask_reg <= 32'hffffc000;
|
||||
end else begin
|
||||
mask_reg <= {KEEP_WIDTH{1'b1}};
|
||||
end
|
||||
end
|
||||
|
||||
if (sum_1_valid_reg) begin
|
||||
sum_2_1_reg <= sum_1_1_reg + sum_1_2_reg;
|
||||
sum_2_2_reg <= sum_1_3_reg + sum_1_4_reg;
|
||||
sum_2_3_reg <= sum_1_5_reg + sum_1_6_reg;
|
||||
sum_2_4_reg <= sum_1_7_reg + sum_1_8_reg;
|
||||
sum_2_valid_reg <= 1'b1;
|
||||
sum_2_last_reg <= sum_1_last_reg;
|
||||
end
|
||||
|
||||
if (sum_2_valid_reg) begin
|
||||
sum_3_1_reg <= sum_2_1_reg + sum_2_2_reg;
|
||||
sum_3_2_reg <= sum_2_3_reg + sum_2_4_reg;
|
||||
sum_3_valid_reg <= 1'b1;
|
||||
sum_3_last_reg <= sum_2_last_reg;
|
||||
end
|
||||
|
||||
if (sum_3_valid_reg) begin
|
||||
sum_4_reg <= sum_3_1_reg + sum_3_2_reg;
|
||||
sum_4_valid_reg <= 1'b1;
|
||||
sum_4_last_reg <= sum_3_last_reg;
|
||||
end
|
||||
|
||||
if (sum_4_valid_reg) begin
|
||||
sum_5_temp = sum_4_reg + sum_5_reg;
|
||||
sum_5_temp = sum_5_temp[15:0] + sum_5_temp[20:16];
|
||||
sum_5_temp = sum_5_temp[15:0] + sum_5_temp[16];
|
||||
|
||||
if (sum_4_last_reg) begin
|
||||
m_axis_csum_reg <= sum_5_temp;
|
||||
m_axis_csum_valid_reg <= 1'b1;
|
||||
sum_5_reg <= 0;
|
||||
end else begin
|
||||
sum_5_reg <= sum_5_temp;
|
||||
end
|
||||
end
|
||||
|
||||
if (rst) begin
|
||||
mask_reg <= 32'hffffc000;
|
||||
sum_1_valid_reg <= 1'b0;
|
||||
sum_2_valid_reg <= 1'b0;
|
||||
sum_3_valid_reg <= 1'b0;
|
||||
sum_4_valid_reg <= 1'b0;
|
||||
m_axis_csum_valid_reg <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
322
fpga/common/tb/test_rx_checksum.py
Executable file
322
fpga/common/tb/test_rx_checksum.py
Executable file
@ -0,0 +1,322 @@
|
||||
#!/usr/bin/env python
|
||||
"""
|
||||
|
||||
Copyright 2019, The Regents of the University of California.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''AS
|
||||
IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
OF SUCH DAMAGE.
|
||||
|
||||
The views and conclusions contained in the software and documentation are those
|
||||
of the authors and should not be interpreted as representing official policies,
|
||||
either expressed or implied, of The Regents of the University of California.
|
||||
|
||||
"""
|
||||
|
||||
from myhdl import *
|
||||
import os
|
||||
|
||||
import axis_ep
|
||||
import eth_ep
|
||||
|
||||
module = 'rx_checksum'
|
||||
testbench = 'test_%s' % module
|
||||
|
||||
srcs = []
|
||||
|
||||
srcs.append("../rtl/%s.v" % module)
|
||||
srcs.append("%s.v" % testbench)
|
||||
|
||||
src = ' '.join(srcs)
|
||||
|
||||
build_cmd = "iverilog -o %s.vvp %s" % (testbench, src)
|
||||
|
||||
def frame_checksum(frame):
|
||||
data = bytearray()
|
||||
if isinstance(frame, eth_ep.EthFrame):
|
||||
data = frame.payload.data
|
||||
elif isinstance(frame, axis_ep.AXIStreamFrame):
|
||||
data = frame.data[14:]
|
||||
else:
|
||||
return None
|
||||
|
||||
csum = 0
|
||||
odd = False
|
||||
|
||||
for b in data:
|
||||
if odd:
|
||||
csum += b
|
||||
else:
|
||||
csum += b << 8
|
||||
odd = not odd
|
||||
|
||||
csum = (csum & 0xffff) + (csum >> 16)
|
||||
csum = (csum & 0xffff) + (csum >> 16)
|
||||
|
||||
return csum
|
||||
|
||||
def bench():
|
||||
|
||||
# Parameters
|
||||
DATA_WIDTH = 256
|
||||
KEEP_WIDTH = (DATA_WIDTH/8)
|
||||
|
||||
# Inputs
|
||||
clk = Signal(bool(0))
|
||||
rst = Signal(bool(0))
|
||||
current_test = Signal(intbv(0)[8:])
|
||||
|
||||
s_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
|
||||
s_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:])
|
||||
s_axis_tvalid = Signal(bool(0))
|
||||
s_axis_tlast = Signal(bool(0))
|
||||
|
||||
# Outputs
|
||||
m_axis_csum = Signal(intbv(0)[16:])
|
||||
m_axis_csum_valid = Signal(bool(0))
|
||||
|
||||
# sources and sinks
|
||||
source_pause = Signal(bool(0))
|
||||
|
||||
source = axis_ep.AXIStreamSource()
|
||||
|
||||
source_logic = source.create_logic(
|
||||
clk,
|
||||
rst,
|
||||
tdata=s_axis_tdata,
|
||||
tkeep=s_axis_tkeep,
|
||||
tvalid=s_axis_tvalid,
|
||||
tlast=s_axis_tlast,
|
||||
pause=source_pause,
|
||||
name='source'
|
||||
)
|
||||
|
||||
sink = axis_ep.AXIStreamSink()
|
||||
|
||||
sink_logic = sink.create_logic(
|
||||
clk,
|
||||
rst,
|
||||
tdata=(m_axis_csum,),
|
||||
tvalid=m_axis_csum_valid,
|
||||
name='sink'
|
||||
)
|
||||
|
||||
# DUT
|
||||
if os.system(build_cmd):
|
||||
raise Exception("Error running build command")
|
||||
|
||||
dut = Cosimulation(
|
||||
"vvp -m myhdl %s.vvp -lxt2" % testbench,
|
||||
clk=clk,
|
||||
rst=rst,
|
||||
current_test=current_test,
|
||||
s_axis_tdata=s_axis_tdata,
|
||||
s_axis_tkeep=s_axis_tkeep,
|
||||
s_axis_tvalid=s_axis_tvalid,
|
||||
s_axis_tlast=s_axis_tlast,
|
||||
m_axis_csum=m_axis_csum,
|
||||
m_axis_csum_valid=m_axis_csum_valid
|
||||
)
|
||||
|
||||
@always(delay(4))
|
||||
def clkgen():
|
||||
clk.next = not clk
|
||||
|
||||
def wait_normal():
|
||||
while s_axis_tvalid:
|
||||
yield clk.posedge
|
||||
|
||||
def wait_pause_source():
|
||||
while s_axis_tvalid:
|
||||
yield clk.posedge
|
||||
yield clk.posedge
|
||||
source_pause.next = False
|
||||
yield clk.posedge
|
||||
source_pause.next = True
|
||||
yield clk.posedge
|
||||
|
||||
source_pause.next = False
|
||||
|
||||
@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
|
||||
|
||||
# testbench stimulus
|
||||
|
||||
for payload_len in list(range(1, 128)) + list([1024, 1500, 9000, 9214]):
|
||||
yield clk.posedge
|
||||
print("test 1: test packet, length %d" % payload_len)
|
||||
current_test.next = 1
|
||||
|
||||
test_frame = eth_ep.EthFrame()
|
||||
test_frame.eth_dest_mac = 0xDAD1D2D3D4D5
|
||||
test_frame.eth_src_mac = 0x5A5152535455
|
||||
test_frame.eth_type = 0x8000
|
||||
test_frame.payload = bytearray((x%256 for x in range(payload_len)))
|
||||
|
||||
axis_frame = test_frame.build_axis()
|
||||
|
||||
for wait in wait_normal, wait_pause_source:
|
||||
source.send(axis_frame)
|
||||
yield clk.posedge
|
||||
yield clk.posedge
|
||||
|
||||
yield wait()
|
||||
|
||||
yield sink.wait()
|
||||
rx_csum = sink.recv().data[0][0]
|
||||
print(hex(rx_csum))
|
||||
|
||||
csum = frame_checksum(test_frame)
|
||||
print(hex(csum))
|
||||
|
||||
assert rx_csum == csum
|
||||
|
||||
assert sink.empty()
|
||||
|
||||
yield delay(100)
|
||||
|
||||
yield clk.posedge
|
||||
print("test 2: back-to-back packets, length %d" % payload_len)
|
||||
current_test.next = 2
|
||||
|
||||
test_frame1 = eth_ep.EthFrame()
|
||||
test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5
|
||||
test_frame1.eth_src_mac = 0x5A5152535455
|
||||
test_frame1.eth_type = 0x8000
|
||||
test_frame1.payload = bytearray((x%256 for x in range(payload_len)))
|
||||
test_frame2 = eth_ep.EthFrame()
|
||||
test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5
|
||||
test_frame2.eth_src_mac = 0x5A5152535455
|
||||
test_frame2.eth_type = 0x8000
|
||||
test_frame2.payload = bytearray((~x%256 for x in range(payload_len)))
|
||||
|
||||
axis_frame1 = test_frame1.build_axis()
|
||||
axis_frame2 = test_frame2.build_axis()
|
||||
|
||||
for wait in wait_normal, wait_pause_source:
|
||||
source.send(axis_frame1)
|
||||
source.send(axis_frame2)
|
||||
yield clk.posedge
|
||||
yield clk.posedge
|
||||
|
||||
yield wait()
|
||||
|
||||
yield sink.wait()
|
||||
rx_csum = sink.recv().data[0][0]
|
||||
print(hex(rx_csum))
|
||||
|
||||
csum = frame_checksum(test_frame1)
|
||||
print(hex(csum))
|
||||
|
||||
assert rx_csum == csum
|
||||
|
||||
yield sink.wait()
|
||||
rx_csum = sink.recv().data[0][0]
|
||||
print(hex(rx_csum))
|
||||
|
||||
csum = frame_checksum(test_frame2)
|
||||
print(hex(csum))
|
||||
|
||||
assert rx_csum == csum
|
||||
|
||||
assert sink.empty()
|
||||
|
||||
yield delay(100)
|
||||
|
||||
yield clk.posedge
|
||||
print("test 3: overflow test")
|
||||
current_test.next = 3
|
||||
|
||||
axis_frame = axis_ep.AXIStreamFrame(bytearray([0xff]*10240))
|
||||
|
||||
for wait in wait_normal, wait_pause_source:
|
||||
source.send(axis_frame)
|
||||
yield clk.posedge
|
||||
yield clk.posedge
|
||||
|
||||
yield wait()
|
||||
|
||||
yield sink.wait()
|
||||
rx_csum = sink.recv().data[0][0]
|
||||
print(hex(rx_csum))
|
||||
|
||||
csum = frame_checksum(axis_frame)
|
||||
print(hex(csum))
|
||||
|
||||
assert rx_csum == csum
|
||||
|
||||
assert sink.empty()
|
||||
|
||||
yield delay(100)
|
||||
|
||||
yield clk.posedge
|
||||
print("test 4: checksum test")
|
||||
current_test.next = 4
|
||||
|
||||
test_frame = eth_ep.EthFrame()
|
||||
test_frame.eth_dest_mac = 0xDA0203040506
|
||||
test_frame.eth_src_mac = 0xCA0203040506
|
||||
test_frame.eth_type = 0x005a
|
||||
test_frame.payload = b'\xab\xcd'+bytearray(range(20, 108))
|
||||
|
||||
axis_frame = test_frame.build_axis()
|
||||
|
||||
for wait in wait_normal, wait_pause_source:
|
||||
source.send(axis_frame)
|
||||
yield clk.posedge
|
||||
yield clk.posedge
|
||||
|
||||
yield wait()
|
||||
|
||||
yield sink.wait()
|
||||
rx_csum = sink.recv().data[0][0]
|
||||
print(hex(rx_csum))
|
||||
|
||||
csum = frame_checksum(test_frame)
|
||||
print(hex(csum))
|
||||
|
||||
assert csum == 0x8ad8
|
||||
assert rx_csum == csum
|
||||
|
||||
assert sink.empty()
|
||||
|
||||
yield delay(100)
|
||||
|
||||
raise StopSimulation
|
||||
|
||||
return instances()
|
||||
|
||||
def test_bench():
|
||||
sim = Simulation(bench())
|
||||
sim.run()
|
||||
|
||||
if __name__ == '__main__':
|
||||
print("Running test...")
|
||||
test_bench()
|
97
fpga/common/tb/test_rx_checksum.v
Normal file
97
fpga/common/tb/test_rx_checksum.v
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
|
||||
Copyright 2019, The Regents of the University of California.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''AS
|
||||
IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
OF SUCH DAMAGE.
|
||||
|
||||
The views and conclusions contained in the software and documentation are those
|
||||
of the authors and should not be interpreted as representing official policies,
|
||||
either expressed or implied, of The Regents of the University of California.
|
||||
|
||||
*/
|
||||
|
||||
// Language: Verilog 2001
|
||||
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
/*
|
||||
* Testbench for rx_checksum
|
||||
*/
|
||||
module test_rx_checksum;
|
||||
|
||||
// Parameters
|
||||
parameter DATA_WIDTH = 256;
|
||||
parameter KEEP_WIDTH = (DATA_WIDTH/8);
|
||||
|
||||
// Inputs
|
||||
reg clk = 0;
|
||||
reg rst = 0;
|
||||
reg [7:0] current_test = 0;
|
||||
|
||||
reg [DATA_WIDTH-1:0] s_axis_tdata = 0;
|
||||
reg [KEEP_WIDTH-1:0] s_axis_tkeep = 0;
|
||||
reg s_axis_tvalid = 0;
|
||||
reg s_axis_tlast = 0;
|
||||
|
||||
// Outputs
|
||||
wire [15:0] m_axis_csum;
|
||||
wire m_axis_csum_valid;
|
||||
|
||||
initial begin
|
||||
// myhdl integration
|
||||
$from_myhdl(
|
||||
clk,
|
||||
rst,
|
||||
current_test,
|
||||
s_axis_tdata,
|
||||
s_axis_tkeep,
|
||||
s_axis_tvalid,
|
||||
s_axis_tlast
|
||||
);
|
||||
$to_myhdl(
|
||||
m_axis_csum,
|
||||
m_axis_csum_valid
|
||||
);
|
||||
|
||||
// dump file
|
||||
$dumpfile("test_rx_checksum.lxt");
|
||||
$dumpvars(0, test_rx_checksum);
|
||||
end
|
||||
|
||||
rx_checksum #(
|
||||
.DATA_WIDTH(DATA_WIDTH),
|
||||
.KEEP_WIDTH(KEEP_WIDTH)
|
||||
)
|
||||
UUT (
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
.s_axis_tdata(s_axis_tdata),
|
||||
.s_axis_tkeep(s_axis_tkeep),
|
||||
.s_axis_tvalid(s_axis_tvalid),
|
||||
.s_axis_tlast(s_axis_tlast),
|
||||
.m_axis_csum(m_axis_csum),
|
||||
.m_axis_csum_valid(m_axis_csum_valid)
|
||||
);
|
||||
|
||||
endmodule
|
Loading…
x
Reference in New Issue
Block a user